Что такое ssh

Порты в Linux

Как мы уже знаем, каждое устройство (компьютер, ноутбук, мобильный телефон, и т.д.) в сети имеет свой собственный IP-адрес. Он уникален для каждого отдельного устройства и дает возможность организовывать сетевые соединения между устройствами. Тем не менее, на отдельном устройстве может быть запущено несколько сетевых приложений одновременно. Порты предоставляют возможность идентифицировать такие сетевые приложения на отдельно взятом компьютере.


Например, некоторые Интернет-сервера имеют несколько одновременно работающих сетевых приложений, таких как веб-сервер (для организации доступа к веб-сайтам на этом сервере), почтовый сервер (для организации получения и отправки сообщений электронной почты) и FTP-сервер (для передачи файлов). Самому физическому серверу в данном случае назначен его уникальный IP-адрес, но если мы попытаемся создать соединение с сервером только по его IP, возникнет проблема неоднозначности — мне не знаем с каким именно приложением мы должны соединиться для обмена данными.

Opening Backdoors into the Enterprise

Remote SSH port forwarding is commonly used by employees to open backdoors into the enterprise. For example, the employee may set get a free-tier server from Amazon AWS, and log in from the office to that server, specifying remote forwarding from a port on the server to some server or application on the internal enterprise network. Multiple remote forwards may be specified to open access to more than one application.

The employee would also set on the server (most employees do not have fixed IP addresses at home, so they cannot restrict the IP address).

For example, the following command opens access to an internal Postgres database at port 5432 and an internal SSH port at port 2222.

Local Forwarding

Local forwarding is used to forward a port from the client machine to the server machine. Basically, the SSH client listens for connections on a configured port, and when it receives a connection, it tunnels the connection to an SSH server. The server connects to a configurated destination port, possibly on a different machine than the SSH server.

Typical uses for local port forwarding include:

  • Tunneling sessions and file transfers through jump servers

  • Connecting to a service on an internal network from the outside

  • Connecting to a remote file share over the Internet

Quite a few organizations for all incoming SSH access through a single jump server. The server may be a standard Linux/Unix box, usually with some extra hardening, intrusion detection, and/or logging, or it may be a commercial jump server solution.

Many jump servers allow incoming port forwarding, once the connection has been authenticated. Such port forwarding is convenient, because it allows tech-savvy users to use internal resources quite transparently. For example, they may forward a port on their local machine to the corporate intranet web server, to an internal mail server’s IMAP port, to a local file server’s 445 and 139 ports, to a printer, to a version control repository, or to almost any other system on the internal network. Frequently, the port is tunneled to an SSH port on an internal machine.

In OpenSSH, local port forwarding is configured using the option:

This example opens a connection to the jump server, and forwards any connection to port 80 on the local machine to port 80 on .

By default, anyone (even on different machines) can connect to the specified port on the SSH client machine. However, this can be restricted to programs on the same host by supplying a bind address:

The option in the OpenSSH client configuration file can be used to configure forwarding without having to specify it on command line.

Установка сервера OpenSSH в Windows

Рассмотрим, как установить компонент OpenSSH Server в Windows 10 1903 (Windows Server 2019 все выполняется аналогично).

Пакет OpenSSH (как и RSAT) уже включен в данные версии Windows в виде Feature on Demand (FoD).

При наличии прямого Интернет-подключения вы можете установить сервер OpenSSH с помощью PowerShell


Или при помощи DISM:

В Windows 10 этот компонент также можно установить через панель Параметры (Приложения -> Управление дополнительными компонентами -> Добавить компонент). Найдите в списке Open SSH Server и нажмите кнопку Install).

Чтобы проверить, что OpenSSH сервер установлен, выполните:

State : Installed

Примеры использования SSH

Команда подключения к локальному SSH-серверу из командной строки GNU/Linux или FreeBSD для пользователя pacify (сервер прослушивает нестандартный порт 30000):

$ ssh -p 30000 pacify@127.0.0.1

Генерация пары ключей (в UNIX-подобных ОС) осуществляется командой

$ ssh-keygen

Генерация пары SSH-2 RSA-ключей длиной 4096 бита программой puttygen под UNIX‐подобными ОС:

$ puttygen -t rsa -b 4096 -o sample

Некоторые клиенты, например, PuTTY, имеют и графический интерфейс пользователя.

Для использования SSH в Python существуют такие модули, как python-paramiko и python-twisted-conch.

Авторизация SSH по ключам

Намного безопаснее, удобнее и правильнее будет настроить ssh авторизацию без пароля. Для этого будет использоваться авторизация по ключу.

Итак, вот инструкция:

  1. Распаковываем архив, открываем PUTTYGEN:

  2. Вводим и выбираем всё как на скриншоте: и ключ длиной и жмём Generate Во время генерации ключей водим мышкой по специальному полю под статусной строкой, чтобы пошла генерация ключей (она использует набор из координат мыши)

  3. Теперь нужно заполнить (это пароль для доступа к приватному ключу). Заполнять не обязательно, но его наличие повысит безопасность, так как любой, кто имеет доступ к приватному ключу, сможет с его помощью авторизоваться на сервере по ssh:

  4. Сохраним приватный ключ где-нибудь в надёжном месте — . Назовём его, к примеру,
  5. А вот публичный ключ нужно сохранить на сервере, куда устанавливаем доступ — Назовём его . Авторизуемся по ssh по паролю и переходим в директорию пользователя, под которым будет происходить авторизация.

    Итак, копируем файл в . Далее нужно импортировать данные в файл

    ssh-keygen -i -f /root/.ssh/sheensay.ru.pub >> /root/.ssh/authorized_keys

    После можно удалить

  6. Осталось настроить подключение. Я пользуюсь Far Manager в связке с плагином WinSCP.

    Открываем Far Manager, Alt + F1, выбираем , далее Shift + F4 и настроим наше подключение. Допустим, мы сохранили приватный файл в При настройке нужно будет указать IP или доменное имя на нём для доступа к серверу, порт, на котором висит SSH, имя пользователя и путь к приватному файлу-ключу

  7. Подключаемся. Если при генерации ключей вы вводили пароль, то в этом случае при подключении у вас будет запрашивать пароль к приватному файлу.

Подключение настроено. Если что-то сделали не так, при авторизации появится ошибка , то есть Сервер не принял наш ключ. В этом случае пройдитесь по всем пунктам последовательно и поищите ошибку

Отключить авторизацию по паролю

Теперь, когда всё настроено, совсем не лишним будет отключить авторизацию по паролю. Для этого внесём изменения в конфигурационный файл:

PasswordAuthentication no

2: Remote port forwarding

  • A remotely forwarded port is just like a local one, but the directions are reversed
  • This time the TCP client is remote, its server is local, and a forwarded connection is initiated from the remote machine.
  • Remote port forwarding is less common and can be used to connect to a local port that cannot be reached from the internet, to a port on the server that is available on the internet
  • The  option specifies remote forwarding. It is followed by three values, separated by colons as before but interpreted slightly differently. 

From the man page of SSH

-R port:host:hostport
-R port:local_socket
-R remote_socket:host:hostport
-R remote_socket:local_socket

             Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be
             forwarded to the given host and port, or Unix socket, on the local side.  This works by allocating a
             socket to listen to either a TCP port or to a Unix socket on the remote side.  Whenever a connection is
             made to this port or Unix socket, the connection is forwarded over the secure channel, and a connection
             is made to either host port hostport, or local_socket, from the local machine.

The syntax to perform Reverse Port Forwarding would be

  • The first field is the bind address on localhost. By default, TCP listening sockets on the server will be bound to the loopback interface only
  • The second field is the which which will be used to connect to the destination port i.e. 80.
  • The third field is for  i.e. the hostname or IP of the server to which you wish to connect as part of forwarding
  • The fourth field is the to which the forwarding should happen on the «»
  • Lastly provide the server details towards which the SSH Tunnel should be created

2.1: Create SSH Tunnel for Remote Port Forwarding

I have a web server with apache on port 80 running on . Now in the earlier examples:

with Local Port Forwarding we forward request from to

Now we will do the opposite i.e.

with Remote Port Forwarding we forward request from to

Create SSH Tunnel on

# ssh -f -N -R localhost:5555:server3:80 root@server1

Make sure the SSH process with the above command is still running

# ps -ef | grep ssh
root      5711     1  0 10:22 ?        00:00:01 sshd: root@pts/0
root      9500     1  0 11:10 ?        00:00:00 /usr/sbin/sshd -D
root     11151  9500  0 12:09 ?        00:00:00 sshd: root@notty
root     13638     1  0 15:46 ?        00:00:00 ssh -f -N -R 5555:server3:80 root@server1
root     13642  5799  0 15:46 pts/0    00:00:00 grep --color=auto ssh

2.2: Verify SSH Tunnel setup

Verify SSH Tunnel Next we will use curl from to connect to server3 using port 5555

# curl  http://localhost:5555
My test site

The connection was successful

With tcpdump running on we can check the secure SSH Tunnel was used for the curl request from to

# tcpdump -i enp0s8 port 22 or 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s8, link-type EN10MB (Ethernet), capture size 262144 bytes
15:48:05.749405 IP server1.ssh > server3.48228: Flags , seq 3747952798:3747952890, ack 3457506699, win 258, options , length 92
15:48:05.749429 IP server3.48228 > server1.ssh: Flags , ack 92, win 291, options , length 0
15:48:05.750020 IP server3.48228 > server1.ssh: Flags , seq 1:45, ack 92, win 291, options , length 44
15:48:05.750314 IP server1.ssh > server3.48228: Flags , ack 45, win 258, options , length 0
15:48:05.750506 IP server1.ssh > server3.48228: Flags , seq 92:208, ack 45, win 258, options , length 116
15:48:05.751491 IP server3.48228 > server1.ssh: Flags , seq 45:337, ack 208, win 291, options , length 292
15:48:05.752605 IP server1.ssh > server3.48228: Flags , seq 208:244, ack 337, win 281, options , length 36
15:48:05.752926 IP server3.48228 > server1.ssh: Flags , seq 337:409, ack 244, win 291, options , length 72
15:48:05.753338 IP server1.ssh > server3.48228: Flags , seq 244:280, ack 409, win 281, options , length 36
15:48:05.793709 IP server3.48228 > server1.ssh: Flags , ack 280, win 291, options , length 0

2.3: Close SSH Tunnel

To close the SSH Tunnel we must kill the SSH process which is running on our

# ps -ef | grep 5555
root     13638     1  0 15:46 ?        00:00:00 ssh -f -N -R 5555:server3:80 root@server1

The PID mapped to the SSH Tunnel is , we will use kill with interrupt signal for the respective PID

# kill -9 13638

Remote port forwarding

This type of port forwarding works in reverse. Say you need to give someone VNC access to your client machine and you want to do so over an encrypted tunnel; with SSH remote port forwarding this is possible.

Before you do this, however, you need to add an option to the /etc/ssh/sshd_config file. Open that file in your editor of choice and add the following line at the bottom:

GatewayPorts yes

Restart the SSH daemon with the command:

sudo systemctl restart sshd

To make this connection happen, you would need to have ssh access to the third-party’s machine. Let’s assume that machine is at IP address 192.168.1.192. To give them an encrypted tunnel for VNC access, you would issue the command:

ssh -R 5900:localhost:5900 USERNAME@192.168.1.192

Where USERNAME is a username you have access to on their machine. You must then authenticate with the USERNAME password on the remote machine. For the duration of the SSH session, the third party would have an encrypted VNC tunnel to your machine, via localhost at port 5900.

And that’s the basics to using local and remote port forwarding with SSH. We’re only scratching the surface as to what port forwarding can do, but this gives you an idea. Port forwarding is an incredibly handy feature that can get you out of some tricky situations. Remember to give the ssh manpage a read (man ssh) to find out more of what SSH can do for you.

Cybersecurity Insider Newsletter

Strengthen your organization’s IT security defenses by keeping abreast of the latest cybersecurity news, solutions, and best practices. Delivered Tuesdays and Thursdays

Sign up today

1.3: Local Port Forwarding with Gateway Ports

  • In OpenSSH, by default, only the host running the SSH client can connect to locally forwarded ports.
  • This is because ssh listens only on the machine’s loopback interface for connections to the forwarded port; i.e., it binds the socket (), a.k.a. (), and not ().
  • So, in the preceding example, only can use the forwarding
  • However, ssh for OpenSSH has a command-line option, , that disables this restriction, permitting any host to connect to locally forwarded ports:
  • The client configuration () keyword also controls this feature; the default value is no, whereas yes does the same thing as

1.3.1: Create SSH Tunnel with Gateway Port

We will also use with our existing SSH command to create the SSH Tunnel. Also if you observe, I have removed «» and have used «» which signifies all the host can be matched

# ssh -g -f -N -L :5555:server3:80 root@server3

Make sure the SSH process is still active for the respective command:

# ps -ef | grep ssh
root      1170     1  0 10:20 ?        00:00:00 /usr/sbin/sshd -D
root      1426  1170  0 10:21 ?        00:00:01 sshd: root@pts/1
root      2242  1170  0 12:31 ?        00:00:00 sshd: root@pts/0
root      2423     1  0 13:01 ?        00:00:00 ssh -g -f -N -L :5555:server3:80 root@server3
root      2425  1430  0 13:03 pts/1    00:00:00 grep --color=auto ssh

1.3.2: Verify the Local Port Forwarding

We will use command from this time to check if it can connect to using port from the secure tunnel

# curl http://server1:5555My test site

So the was successfully able to connect to and also to the webserver using forwarding port

The tcpdump output from shows that the connection was established between and using secure tunnel to get the HTTP request. You can extend the to search for host to get packet details from respective host. Since the tunnel is between and only, we do not see related details here.

# tcpdump -i enp0s8 port 22 or 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s8, link-type EN10MB (Ethernet), capture size 262144 bytes
13:01:40.344612 IP server1.53480 > server3.ssh: Flags , seq 2488865116:2488865208, ack 1385274191, win 309, options , length 92
13:01:40.344639 IP server3.ssh > server1.53480: Flags , ack 92, win 295, options , length 0
13:01:40.346140 IP server3.ssh > server1.53480: Flags , seq 1:45, ack 92, win 295, options , length 44
13:01:40.346422 IP server1.53480 > server3.ssh: Flags , ack 45, win 309, options , length 0
13:01:40.346507 IP server1.53480 > server3.ssh: Flags , seq 92:208, ack 45, win 309, options , length 116
13:01:40.347088 IP server3.ssh > server1.53480: Flags , seq 45:337, ack 208, win 295, options , length 292
13:01:40.347943 IP server1.53480 > server3.ssh: Flags , seq 208:244, ack 337, win 329, options , length 36
13:01:40.348239 IP server3.ssh > server1.53480: Flags , seq 337:409, ack 244, win 295, options , length 72
13:01:40.348453 IP server1.53480 > server3.ssh: Flags , seq 244:280, ack 409, win 329, options , length 36
13:01:40.389600 IP server3.ssh > server1.53480: Flags , ack 280, win 295, options , length 0

1.3.3: Close SSH Tunnel


Close the SSH Tunnel To close the Local forwarding port, you can go ahead and kill the SSH process which we created earlier to start the tunnel from

# kill -9 2423

Dynamic Port Forwarding with the OpenSSH SSH Client

The OpenSSH SSH client is shipped with almost every Linux distribution. The following command will connect you to the remote SSH server and at the same time enable dynamic port forwarding.

ssh -D port-number 

If you have a user john on the remote SSH server 12.34.56.78, then you can run:

ssh -D 1080 

Enter the password for user john. option enables dynamic port forwarding. 1080 is a common port. You can also use other port such as 8080.

After you run this command, a secure SSH tunnel with dynamic port forwarding will be established between your Linux PC and your SSH server. The ssh client will be listening on 127.0.0.1:1080 acting as a local SOCKS proxy server. You can check this out with

sudo netstat -lnpt

1.2: Local Port Forwarding with three servers

In this example we will have three servers. Here does not has direct access to so it will use → to connect to the webserver on .

We will forward the port request from to using secure SSH Tunnel which will further connect to fetch the request.

1.2.1: Create SSH Tunnel

Create Local Forwarding port on your localhost () using SSH client. You can also ignore mentioning localhost in this command as that is the default behaviour, I have written here just for the sake of explanation

# ssh -f -N -L localhost:5555:server3:80 root@server2

Make sure the SSH process is active which means our tunnel is created

# ps -ef | grep ssh
root      1170     1  0 10:20 ?        00:00:00 /usr/sbin/sshd -D
root      1426  1170  0 10:21 ?        00:00:01 sshd: root@pts/1
root      2242  1170  0 12:31 ?        00:00:00 sshd: root@pts/0
root      2380     1  0 12:51 ?        00:00:00 ssh -f -N -L localhost:5555:server3:80 root@server2
root      2382  1430  0 12:51 pts/1    00:00:00 grep --color=auto ssh

1.2.2: Verify the SSH Tunnel

We will use to connect to our webserver on from using . So the curl tool was successfully able to fetch the webserver’s index page.

# curl  http://localhost:5555
My test site

You can check the tcpdump capture on This shows the secure tunnel communication between and and further will connect to to connect to the webserver. 

# tcpdump -i enp0s8 port 22 or 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s8, link-type EN10MB (Ethernet), capture size 262144 bytes
12:59:04.138042 IP server1.60638 > server2.ssh: Flags , seq 2758738467:2758738551, ack 379740010, win 289, options , length 84
12:59:04.138269 IP server2.ssh > server1.60638: Flags , ack 84, win 273, options , length 0
12:59:04.144056 IP server2.53650 > server3.http: Flags , seq 2208701817, win 29200, options , length 0
12:59:04.144073 IP server3.http > server2.53650: Flags , seq 2805768777, ack 2208701818, win 28960, options , length 0
12:59:04.148666 IP server2.53650 > server3.http: Flags , ack 1, win 229, options , length 0
12:59:04.148672 IP server2.ssh > server1.60638: Flags , seq 1:45, ack 84, win 273, options , length 44
12:59:04.148790 IP server1.60638 > server2.ssh: Flags , ack 45, win 289, options , length 0
12:59:04.148917 IP server1.60638 > server2.ssh: Flags , seq 84:200, ack 45, win 289, options , length 116
12:59:04.149100 IP server2.53650 > server3.http: Flags , seq 1:79, ack 1, win 229, options , length 78: HTTP: GET / HTTP/1.1
12:59:04.149118 IP server3.http > server2.53650: Flags , ack 79, win 227, options , length 0
12:59:04.149546 IP server3.http > server2.53650: Flags , seq 1:254, ack 79, win 227, options , length 253: HTTP: HTTP/1.1 200 OK

1.2.3: Close Local forwarding Tunnel

To close the secure SSH Tunnel, go ahead and kill the respective SSH process which we created earlier:

# kill -9  2380

Server Configurations

The SSH server must be configured to allow port forwarding. By default, port forwarding is allowed. You can control this behavior by using the AllowTCPForwarding option. To allow SSH Forwarding, open the SSH daemon configuration file (usually /etc/ssh/sshd_config) and add or modify the following line.

To denied forwarding:

When reverse forwarding is enabled from a one system to another, anyone that has access to the port on that host server will be forwarded to the client. This can be controlled by using the GatewayPorts option in the SSH daemon configuration.

To prevent connecting to forwarded ports from outside the server, add or modify the following line in the configuration.

To allow anyone to connect to the forwarding ports:

Советы по безопасности использования SSH

  1. Запрет на удалённый root-доступ.
  2. Запрет подключения с пустым паролем или отключение входа по паролю.
  3. Выбор нестандартного порта для SSH-сервера.
  4. Использование длинных SSH2 RSA-ключей (2048 бит и более). Системы шифрования на основе RSA считаются надёжными, если длина ключа не менее 1024 бит.
  5. Ограничение списка IP-адресов, с которых разрешён доступ (например, настройкой файервола).
  6. Запрет доступа с некоторых потенциально опасных адресов.
  7. Отказ от использования распространённых или широко известных системных логинов для доступа по SSH.
  8. Регулярный просмотр сообщений об ошибках аутентификации.
  9. Установка систем обнаружения вторжений (IDS).[источник не указан 1407 дней]
  10. Использование ловушек, подделывающих SSH-сервис (honeypot).
  11. Реализация технологии

С этим читают