使用 stunnel 保护 telnet 连接
telnet stunnel
![](/data/attachment/album/201906/06/134640cuu5x9ni09y696my.jpg)


Telnet 是一种客户端-服务端协议，通过 TCP 的 23 端口连接到远程服务器。Telnet 并不加密数据，因此它被认为是不安全的，因为数据是以明文形式发送的，所以密码很容易被嗅探。但是，仍有老旧系统需要使用它。这就是用到 **stunnel** 的地方。


stunnel 旨在为使用不安全连接协议的程序增加 SSL 加密。本文将以 telnet 为例介绍如何使用它。


### 服务端安装


[使用 sudo](https://fedoramagazine.org/howto-use-sudo/) 安装 stunnel 以及 telnet 的服务端和客户端：



```
sudo dnf -y install stunnel telnet-server telnet
```

添加防火墙规则，在提示时输入你的密码：



```
firewall-cmd --add-service=telnet --perm
firewall-cmd --reload
```

接下来，生成 RSA 私钥和 SSL 证书：



```
openssl genrsa 2048 > stunnel.key
openssl req -new -key stunnel.key -x509 -days 90 -out stunnel.crt
```

系统将一次提示你输入以下信息。当询问 `Common Name` 时，你必须输入正确的主机名或 IP 地址，但是你可以按回车键跳过其他所有内容。



```
You are about to be asked to enter information that will be
incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []
```

将 RSA 密钥和 SSL 证书合并到单个 `.pem` 文件中，并将其复制到 SSL 证书目录：



```
cat stunnel.crt stunnel.key > stunnel.pem
sudo cp stunnel.pem /etc/pki/tls/certs/
```

现在可以定义服务和用于加密连接的端口了。选择尚未使用的端口。此例使用 450 端口进行隧道传输 telnet。编辑或创建 `/etc/stunnel/telnet.conf`：



```
cert = /etc/pki/tls/certs/stunnel.pem
sslVersion = TLSv1
chroot = /var/run/stunnel
setuid = nobody
setgid = nobody
pid = /stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
[telnet]
accept = 450
connect = 23
```

`accept` 选项是服务器将监听传入 telnet 请求的接口。`connect` 选项是 telnet 服务器的内部监听接口。


接下来，创建一个 systemd 单元文件的副本来覆盖原来的版本：



```
sudo cp /usr/lib/systemd/system/stunnel.service /etc/systemd/system
```

编辑 `/etc/systemd/system/stunnel.service` 来添加两行。这些行在启动时为服务创建 chroot 监狱。



```
[Unit]
Description=TLS tunnel for network daemons
After=syslog.target network.target

[Service]
ExecStart=/usr/bin/stunnel
Type=forking
PrivateTmp=true
ExecStartPre=-/usr/bin/mkdir /var/run/stunnel
ExecStartPre=/usr/bin/chown -R nobody:nobody /var/run/stunnel

[Install]
WantedBy=multi-user.target
```

接下来，配置 SELinux 以在你刚刚指定的新端口上监听 telnet：



```
sudo semanage port -a -t telnetd_port_t -p tcp 450
```

最后，添加新的防火墙规则：



```
firewall-cmd --add-port=450/tcp --perm
firewall-cmd --reload
```

现在你可以启用并启动 telnet 和 stunnel。



```
systemctl enable telnet.socket stunnel@telnet.service --now
```

要注意 `systemctl` 命令是有顺序的。systemd 和 stunnel 包默认提供额外的[模板单元文件](https://fedoramagazine.org/systemd-template-unit-files/)。该模板允许你将 stunnel 的多个配置文件放到 `/etc/stunnel` 中，并使用文件名启动该服务。例如，如果你有一个 `foobar.conf` 文件，那么可以使用 `systemctl start stunnel@foobar.service` 启动该 stunnel 实例，而无需自己编写任何单元文件。


如果需要，可以将此 stunnel 模板服务设置为在启动时启动：



```
systemctl enable stunnel@telnet.service
```

### 客户端安装


本文的这部分假设你在客户端系统上以普通用户（[拥有 sudo 权限](https://fedoramagazine.org/howto-use-sudo/)）身份登录。安装 stunnel 和 telnet 客户端：



```
dnf -y install stunnel telnet
```

将 `stunnel.pem` 从远程服务器复制到客户端的 `/etc/pki/tls/certs` 目录。在此例中，远程 telnet 服务器的 IP 地址为 `192.168.1.143`。



```
sudo scp myuser@192.168.1.143:/etc/pki/tls/certs/stunnel.pem
/etc/pki/tls/certs/
```

创建 `/etc/stunnel/telnet.conf`：



```
cert = /etc/pki/tls/certs/stunnel.pem
client=yes
[telnet]
accept=450
connect=192.168.1.143:450
```

`accept` 选项是用于 telnet 会话的端口。`connect` 选项是你远程服务器的 IP 地址以及监听的端口。


接下来，启用并启动 stunnel：



```
systemctl enable stunnel@telnet.service --now
```

测试你的连接。由于有一条已建立的连接，你会 `telnet` 到 `localhost` 而不是远程 telnet 服务器的主机名或者 IP 地址。



```
[user@client ~]$ telnet localhost 450
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Kernel 5.0.9-301.fc30.x86_64 on an x86_64 (0)
server login: myuser
Password: XXXXXXX
Last login: Sun May  5 14:28:22 from localhost
[myuser@server ~]$
```



---


via: <https://fedoramagazine.org/securing-telnet-connections-with-stunnel/>


作者：[Curt Warfield](https://fedoramagazine.org/author/rcurtiswarfield/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Telnet is a client-server protocol that connects to a remote server through TCP over port 23. Telnet does not encrypt data and is considered insecure and passwords can be easily sniffed because data is sent in the clear. However there are still legacy systems that need to use it. This is where **stunnel** comes to the rescue.

Stunnel is designed to add SSL encryption to programs that have insecure connection protocols. This article shows you how to use it, with telnet as an example.

## Server Installation

Install stunnel along with the telnet server and client [using sudo](https://fedoramagazine.org/howto-use-sudo/):

sudo dnf -y install stunnel telnet-server telnet

Add a firewall rule, entering your password when prompted:

firewall-cmd --add-service=telnet --perm

firewall-cmd --reload

Next, generate an RSA private key and an SSL certificate:

openssl genrsa 2048 > stunnel.key

openssl req -new -key stunnel.key -x509 -days 90 -out stunnel.crt

You will be prompted for the following information one line at a time. When asked for *Common Name* you must enter the correct host name or IP address, but everything else you can skip through by hitting the **Enter** key.

You are about to be asked to enter information that will be

incorporated into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [XX]:

State or Province Name (full name) []:

Locality Name (eg, city) [Default City]:

Organization Name (eg, company) [Default Company Ltd]:

Organizational Unit Name (eg, section) []:

Common Name (eg, your name or your server's hostname) []:

Email Address []

Merge the RSA key and SSL certificate into a single *.pem* file, and copy that to the SSL certificate directory:

cat stunnel.crt stunnel.key > stunnel.pem

sudo cp stunnel.pem /etc/pki/tls/certs/

Now it’s time to define the service and the ports to use for encrypting your connection. Choose a port that is not already in use. This example uses port 450 for tunneling telnet. Edit or create the */etc/stunnel/telnet.conf* file:

cert = /etc/pki/tls/certs/stunnel.pem

sslVersion = TLSv1

chroot = /var/run/stunnel

setuid = nobody

setgid = nobody

pid = /stunnel.pid

socket = l:TCP_NODELAY=1

socket = r:TCP_NODELAY=1

[telnet]

accept = 450

connect = 23

The **accept **option is the port the server will listen to for incoming telnet requests. The **connect** option is the internal port the telnet server listens to.

Next, make a copy of the systemd unit file that allows you to override the packaged version:

sudo cp /usr/lib/systemd/system/stunnel.service /etc/systemd/system

Edit the */etc/systemd/system/stunnel.service* file to add two lines. These lines create a chroot jail for the service when it starts.

[Unit]

Description=TLS tunnel for network daemons

After=syslog.target network.target

[Service]

ExecStart=/usr/bin/stunnel

Type=forking

PrivateTmp=trueExecStartPre=-/usr/bin/mkdir /var/run/stunnel

ExecStartPre=/usr/bin/chown -R nobody:nobody /var/run/stunnel

[Install]

WantedBy=multi-user.target

Next, configure SELinux to listen to telnet on the new port you just specified:

sudo semanage port -a -t telnetd_port_t -p tcp 450

Finally, add a new firewall rule:

firewall-cmd --add-port=450/tcp --perm

firewall-cmd --reload

Now you can enable and start telnet and stunnel.

systemctl enable telnet.socket stunnel@telnet.service --now

A note on the *systemctl* command is in order. Systemd and the stunnel package provide an additional [template unit file](https://fedoramagazine.org/systemd-template-unit-files/) by default. The template lets you drop multiple configuration files for stunnel into */etc/stunnel*, and use the filename to start the service. For instance, if you had a *foobar.conf* file, you could start that instance of stunnel with *systemctl start stunnel@foobar.service*, without having to write any unit files yourself.

If you want, you can set this stunnel template service to start on boot:

systemctl enable stunnel@telnet.service

## Client Installation

This part of the article assumes you are logged in as a normal user ([with sudo privileges](https://fedoramagazine.org/howto-use-sudo/)) on the client system. Install stunnel and the telnet client:

dnf -y install stunnel telnet

Copy the *stunnel.pem* file from the remote server to your client */etc/pki/tls/certs* directory. In this example, the IP address of the remote telnet server is 192.168.1.143.

sudo scp myuser@192.168.1.143:/etc/pki/tls/certs/stunnel.pem

/etc/pki/tls/certs/

Create the */etc/stunnel/telnet.conf* file:

cert = /etc/pki/tls/certs/stunnel.pem

client=yes

[telnet]

accept=450

connect=192.168.1.143:450

The **accept **option is the port that will be used for telnet sessions. The **connect** option is the IP address of your remote server and the port it’s listening on.

Next, enable and start stunnel:

systemctl enable stunnel@telnet.service --now

Test your connection. Since you have a connection established, you will telnet to *localhost* instead of the hostname or IP address of the remote telnet server:

[user@client ~]$telnet localhost 450

Trying ::1...

telnet: connect to address ::1: Connection refused

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

Kernel 5.0.9-301.fc30.x86_64 on an x86_64 (0)

server login:myuser

Password:XXXXXXX

Last login: Sun May 5 14:28:22 from localhost

[myuser@server ~]$

## Paul Gresham

Thank you Curt. This and other articles in the Fedora Magazine are outstanding.

## Curt Warfield

You’re welcome. Thanks so much for your feedback.

## Einer

I guess I don’t see the point of this because:

1) I would not use the telnet server

2) If I am going to put something in an encrypted tunnel, I would just use SSH

## Curt Warfield

Hi Einer,

There are a lot of legacy systems that still need to use telnet.

The point of the article is to show you how to make your telnet sessions more secure if you are in a situation where you need to use it.

## Einer

Hi Curt 🙂

I am not so sure I agree with you. Here’s why:

1) let’s say its a Cisco router

2) can only use telnet to get a console session on the router via the network

1) you can’t install stunnel on that Cisco router

== no way to encapsulate the telnet session in SSL/stunnel== wasted effort 🙂

same applies to an old Unix system that has no support for stunnel

Bottom line is that BOTH ends of the conversation/session must be able to support stunnel ……. if you can’t install on one end or the other (most likely due to age of one of the endpoints) …………

see where I’m going? 🙂

## Supersonic Tumbleweed

You can very much use telnet with ssh, ssh with telnet, and any combination of those you can think of… so it’s an additional layer of configs.

But also an additional layer of abstraction for programs that have telnet invocation hardcoded into them, that allows to work with those programs securely too, so that’s nice.

## Supersonic Tumbleweed

Actually, scratch that, it just opens a tunnel.

Yeah, that can be done pretty easily without an additional tool. Nice for managing keys.

## Stuart D Gathman

The title is misleading. The point is to illustrate how to use stunnel with something simple like telnet. The point is that you can add security to any TCP service with stunnel. Telnet is just a simple example. Did you build a simple tcp service in python? Don’t want to deal with adding SSL support for use over the public internet? Use stunnel!

## Radosław

I see several issues with this article, assuming that it is aimed towards beginners.

There’s little point in generating insecure, self-signed certificates, when Let’s Encrypt is available and well integrated in Fedora. I strongly believe that recommending self-signed certificates is harmful. The article should be updated to reference certbot or at least explain why is it a terrible idea to use self-signed certs.

Also, when you’re using stunnel for a single, local service that you want to provide as encrypted, I’d say it is much better idea to use systemd socket activation. This way it won’t be necessary to restart stunnel service every time you update the certificate (because it will be started on-demand by systemd every time when the incoming connection arrives).

The encrypted-telnet.socket file could look like:

[Socket]

ListenStream=450

Accept=yes

[Install]

WantedBy=sockets.target

And the appropriate encrypted-telnet@.service:

[Service]

ExecStart=/usr/bin/stunnel /etc/stunnel/telnet.conf

StandardInput=socket

[Install]

WantedBy=multi-user.target

The stunnel server telnet.conf file would also be much simpler:

cert = /etc/letsencrypt/live/example.com/fullchain.pem

key = /etc/letsencrypt/live/example.com/privkey.pem

connect = localhost:450

Much easier, yes?

## Radosław

And of course I made a mistake in the example above, as connect should be done to local port 23, so:

connect = localhost:23

## Bob

Using self-signed certificates are no more or less secure than certificates signed by a CA like Let’s Encrypt. The purpose of the CA is to help us trust other certificates more easily. By trusting a CA you trust all certificates issued by it. If you’re building an STunnel connection and are in control of both sides of the connection and the certificates in use their is no reason not to trust the self-signed certificates you generate.

## Curt Warfield

Thanks for your feedback. I appreciate it!

## varesa

Self-signed certificates can be quite useful in self contained internal systems. Unless you can/want to use certificate pinning, it can even be more secure as then nobody but you (unlike for example a third party CA) can issue certificates to impersonate your secure connection.

Useful for web services? Not really. Useful for internal secure tunneling (VPNs, etc.)? Yes

## ss

I wouldn’t personally use Stunnel+telnet as the other commenter wrote but it is still useful for securing of any TCP service – maybe POP3 server or some embedded REST clients. I usually use SSH or ncat –ssl for quick security but If I ever need a certificates issued by a trusted CA, stunnel would probably do the job

## Ed H.

That’s a lot of configuration tweaks. Why not just use secure shell (ssh)?

## wsanders

Best way to handle telnet:

yum erase telnet

I haven’t installed it in years. If you need to test a TCP connection use nc.

## wsanders

However, to edit that remark, stunnel is useful.