最後更新: 2019-10-02
目錄
- Local Port Forward (-L)
- Reverse ssh tunnel (-R)
- Remote forward(-R) with 0.0.0.0
- Local forward(-L) with 0.0.0.0
- Dynamic Proxy
- ssh 時自動建立 tunnel
-
putty ssh tunnel
Socks5 Proxy - putty SOCKS v5
- autossh
- sidedoor
- ~/.ssh/config
- sshd 限制只可以 tunnel 去某 IP:Port
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 連線後執行於背景
以上兩參數缺一不可 !!
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