ssh tunnel 與 autossh

最後更新: 2019-10-02

目錄

 


Local Port Forward (-L)

 

Diagram

# 相當於 Local 的 8888 map 成 WWW 的 80

          Client ------------------> Host -------------------> WWW-Server
                        tunnel                 unencrypted
port       8888                       22                        80
        ssh_clinet                ssh_server                    www

Usage

ssh -N -f  [username@my_ssh_server] -L [lport]:[remote_host]:[rport]

Example

ssh -NT -f  user@host   -L  8888:WWW-Server:80

  • -N      Do not execute a remote command.
             它決定在 server 上用 "none" 這個 subsystem
             "default" 係 shell 來
  • -T      Disable pseudo-tty allocation
  • -f      "連線後於背景執行"

 


Reverse ssh tunnel (-R)

 

一般來說, 這功能是用在 "有出無入" 的地方, 比如 Source 是在 Firewall 後, 而你又想從外面連入去

Diagram

[SSH_Client] --ssh--[firewall]--ssh--> [SSH_Server(Port:22)]

[SSH_Client] -------[firewall]-------- SSH_Server
                                            |
                                            |
127.0.0.1:22     <---by_pass_fw---    127.0.0.1:2222

Usage

# remote_port:localhost:local_port

ssh -R 2222:localhost:22 user@source

Example:

Step_1: 在 firewall 後的 client ssh 出去

Step_2: 成功後, Firewall 外的 Server 的 Port 2222 相當卡 Firewall 後 Server 的 Port 22

 * port 最好用 > 1024, 因為低 port 只有 root 才用到

 


Remote forward(-R) with 0.0.0.0

 

GatewayPorts

Enabling it will instruct sshd to allow remote port forwardings to bind to a non-loopback address.
(by default it is disabled)

/etc/ssh/sshd_config

Match User root
   GatewayPorts yes

client cmd

-R 8080:127.0.0.1:8080       # 它是指 127.0.0.1:8080

-R :8080:127.0.0.1:8080      # 它是指 0.0.0.0:8080 !!

openwrt 的 sshd (dropbear)

/etc/config/dropbear

config dropbear
        option PasswordAuth 'on'
        option RootPasswordAuth 'on'
        option GatewayPorts 'on'
        option Port         '22'

 


Local forward(-L) with 0.0.0.0

 

# -g    Allows remote hosts to connect to local forwarded ports.

ssh -g -L 8001:localhost:8000 root@remote-machine

沒有加 "-g" 時

netstat -nlt | grep 8080

tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN

加了 "-g"

netstat -nlt | grep 8080

tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN

 


Dynamic Proxy

 

-D [bind_address:]port

ssh -D 10080 -fN user@jumphost

# wget, curl, yum 都會用此 Environment Variable

export http_proxy=http://SERVER:PORT/

e.g.

# 利用 ssh tunnel 做 proxy

export http_proxy=http://localhost:10080/

yum settings

/etc/yum.conf

proxy=socks5://localhost:10080

 


ssh 時自動建立 tunnel

 

修改 ~/.ssh/config

加下

# 一行一個 forward
LocalForward [bind_address:]Lport Rhost:Rport

效果相當於

ssh -f -N Lport:Rhost:Rport

 


putty ssh tunnel

 

ssh 亦可以作 vpn 之用, 真是不講不知 !!!

 

工具 pietty:

在 Source port 填 8080

Destination 填 192.168.1.1:80

網頁:

那在 IE 網址填 http://127.0.0.1:8080 ,

就可連上綁在 loopback interface 的 Web Server

ftp:

如果係作 ftp 的 21 加蜜的話, 記得要以 passive mode 登入,

而 server 那裡要有 "pasv_promiscuous=YES" 的設定 (以上是 ftp 的設定)

對比 Linux 上的應用

ssh -f -N -L 2121:192.168.1.1:21 [email protected]

-N    不建立shell

-f     連線後執行於背景

以上兩參數缺一不可 !!

Socks5 Proxy

Putty Setting:

Path: Settings -> Connection -> SSH _Tunnels

Source Port: 1080
Destination: BLANK
Type: Dynamic

Checking:

netstat -an | find "10080"

  TCP    127.0.0.1:1080        0.0.0.0:0              LISTENING

Firefox Setting:

https://datahunter.org/firefox#proxy_setting

Reverse Tunnel Setting

 

 


Disable interactive shell access while tunneling

 

[方法1]

For any tunnelling-only user, change their login shell to /sbin/nologin

[方法2]

authorized_keys

command="/sbin/nologin",no-pty ssh-rsa ...

[方法3]

Match group proxy-only
    ForceCommand /sbin/nologin
    PermitTTY no
    ...

Checking

# Test by ssh

ssh sshtunnel

--

PermitTTY no

PTY allocation request failed on channel 0

--

ForceCommand /sbin/nologin

This account is currently not available.
Connection to SERVER closed.

--

ChrootDirectory %h

Write failed: Broken pipe

 


Chroot Tunnel Environment

 

詳見

 


Proxy Only

 

AllowTcpForwarding

Specifies whether TCP forwarding is permitted.

  • 'yes' (the default) or 'all' to allow TCP forwarding,
  • 'no' to prevent all TCP forwarding,
  • 'local' to allow local forwarding only or
  • 'remote' to allow remote forwarding only.

PermitTunnel

Specifies whether tun(4) device forwarding is allowed

  • yes(permits both point-to-point and ethernet)
  • point-to-point (layer 3)
  • ethernet (layer 2)
  • no (default)

AllowStreamLocalForwarding

Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted.

  • yes (the default) or all to allow StreamLocal forwarding,
  • no to prevent all StreamLocal forwarding,
  • local to allow local (from the perspective of ssh(1)) forwarding only or
  • remote to allow remote forwarding only. 

AllowTcpForwarding remote

AllowStreamLocalForwarding no

GatewayPorts yes

 


Example: proxy-only

 

"proxy-only" Group

Match group proxy-only
    X11Forwarding no
    PermitTunnel no
    GatewayPorts yes
    AllowTcpForwarding remote
    ForceCommand /sbin/nologin
    PermitTTY no
    PermitRootLogin no
    KbdInteractiveAuthentication no
    PasswordAuthentication no
    PubkeyAuthentication yes

 



autossh

 

功能:

monitor and restart ssh sessions

The original idea and the mechanism were from rstunnel (Reliable SSH Tunnel).

安裝:

# Centos 7

yum install autossh

# Check Version

autossh -V

autossh 1.4e

原理:

autossh -M 0 -L 5000:localhost:3306 [email protected]

相當於

ssh -L 5000:localhost:3306 [email protected]

Usage

autossh [-V] [-M monitor_port[:echo_port]] [-f] [SSH_OPTIONS]

-f       # causes autossh to drop to the background before running ssh.

         # The -f flag is stripped from arguments passed to ssh.

         # When -f is used, the "starting gate" time is set to 0.

         # 用 -f 必須 public/private key authentification

AUTOSSH_GATETIME

             Specifies how long ssh must be up before we consider it a successful connection. Default: 30 sec

-M port[:echo_port]

-M N

Specifies the base monitoring port to use.

Without the echo port, this port and the port immediately above it ( port + 1) should be something nothing else is using.

autossh will send test data on the base monitoring port, and receive it back on the port above. For example,

if you specify "-M 20000", autossh will set up forwards so that it can send data on port 20000 and receive it back on 20001.

-M 0

Setting the monitor port to 0 turns the monitoring function off, and autossh will only restart ssh upon ssh's exit.

For example, if you are using a recent version of OpenSSH,

you may wish to explore using the ServerAliveInterval and ServerAliveCountMax options

to have the SSH client exit if it finds itself no longer connected to the server.

In many ways this may be a better solution than the monitoring port.

ServerAliveInterval (Default: 0)

Sets a timeout interval in seconds after which if no data has been received from the server,

ssh will send a message through the encrypted channel to request a response from the server.

ServerAliveCountMax (Default: 3)

If this threshold is reached while server alive messages are being sent,

ssh will disconnect from the server, terminating the session.

# Default Values:

autossh -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3"

Server Side:

建立 user

useradd -m -s /bin/false autossh

建立 key

su -s /bin/bash autossh

ssh-keygen

mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys

cat ~/.ssh/id_rsa

Client Side:

# Basic

autossh -M 0 -R 2222:localhost:22 autossh@remotemachine

 * 最小切需要加 "-M 0"

# 測試

mkdir ~/ssh-key

chmod 700 ~/ssh-key

# 保存上個 step cat 出來的 key

vim ~/ssh-key/sshgw.key

chmod 400 /root/ssh-key/sshgw.key

autossh -N -M 0-R 2222:localhost:22 autossh@remotemachine -i /root/ssh-key/sshgw.key

-N      Do not execute a remote command. 沒有 -N 時, 那會獲得一個 shell

# 成功得在 server side 會見到

netstat -ntlp | grep ssh

tcp   0      0 127.0.0.1:2222   0.0.0.0:*    LISTEN   3092/sshd

# 斷線測試

killall -u autossh

log (/var/log/messages)

Jul 21 16:30:24 centos7 autossh[13647]: ssh exited with error status 255; restarting ssh
Jul 21 16:30:24 centos7 autossh[13647]: starting ssh (count 3)
Jul 21 16:30:24 centos7 autossh[13647]: ssh child pid is 13657

systemd:

/etc/systemd/system/autossh-mysql-tunnel.service

[Unit]
Description=AutoSSH tunnel service everythingcli MySQL on local port 5000
After=network.target

[Service]
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -NL 5000:localhost:3306 autossh@myserver -p 1022

[Install]
WantedBy=multi-user.target

systemctl daemon-reload

systemctl start autossh-mysql-tunnel.service

systemctl enable autossh-mysql-tunnel.service

 


sidedoor

 

SSH connection daemon

https://github.com/daradib/sidedoor

sidedoor maintains an SSH connection or tunnel with a shell script daemon.

 - /bin/sh

 - while true; do

與 autossh 比較

sidedoor is a minimalistic shell script daemon.

autossh is a more extensive and configurable C program.
 

 


~/.ssh/config

 

~/.ssh/config

Host remotemachine
  HostName      192.168.88.116
  User          autossh
  Port          22
  IdentityFile  ~/ssh-key/sshgw.key

  ServerAliveInterval 10
  ServerAliveCountMax 3

  # local 的 13306 相當於 remote 的 3306
  #LocalForward  13306 localhost:3306
 
  # remote 的 2222 相當於 local 的 22
  RemoteForward  2222 localhost:22
 

 


sshd 限制只可以 tunnel 去某 IP:Port

 

/etc/ssh/sshd_config

Match User some-user
   #AllowTcpForwarding yes
   #PermitTunnel no
   #GatewayPorts no
   X11Forwarding no
   AllowAgentForwarding no
   PermitOpen localhost:3306
   ForceCommand echo 'This account can only be used for mysql tunnel'

PermitOpen

Limit local 'ssh -L' port forwarding (limit connect to the specified host and port)

Multiple forwards may be specified by separating them with whitespace

PermitOpen *:*            # Default
PermitOpen host:port
PermitOpen none

* 如果 User 有得 shell access, 那 PermitOpen 限制形同虛設, 因為 User 可以用 rinetd

P.S.

AllowTcpForwarding yes(Default) | no | local | remote |

local: to allow local

remote:  to allow remote forwarding only

 

 

Creative Commons license icon Creative Commons license icon