[关闭]
@zsh-o 2019-04-07T18:55:39.000000Z 字数 2771 阅读 1546

实验室反向外网

杂项


实验室配了服务器,为了能够在本人不在实验室的情况下能愉快的做实验,配合阿里云的公网ip做了一个公网链接实验室ssh和jupyter的方法。经过好几次的尝试,终于找到了一个比较稳定的方法。另外只是jupyter notebook而不是server版的jupyterhub,由于jupyterhub会有用户代理这一说,新用户登录会随机自动spawn出一个登录端口,这对于我们用于反向的有限的固定端口来说是非常不友好的。

原理:利用ssh的反向端口转发功能,从实验室主动与远程服务器建立隧道,再在远程服务器做一次端口转发,实现端口的数据访问被转发该隧道,从而实现公网ip:端口的方式访问个人局域网中的服务器。由于这样建立的ssh会莫名自动断开,这种隧道型的方式对断线的处理需要自动控制,所以尝试了各种方法,另外的问题是实验室的电脑存在网络不稳定,断网,改ip,断电等不稳定因素,所以需要有一个自动重连远服务器的功能

这个地方的优点在于远程服务器自己的端口转发是可以一直保持转发,而且与源端口是否有数据无关,所以只要做好实验室这边的重连就可以了

所需工具

首先是服务器运行的脚本:start_zsh.sh

  1. #!/bin/sh
  2. # start_zsh.sh
  3. . /home/zsh_o/anaconda3/etc/profile.d/conda.sh
  4. conda activate py3
  5. cd /home/zsh_o/jupyter
  6. result=`ps aux | grep -i "jupyter-notebook --no-browser --ip 0.0.0.0 --NotebookApp.token=zhangheng --port=8888" | grep -v "grep" | wc -l`
  7. if [ $result -ge 1 ]
  8. then
  9. echo 'jupyter is running'
  10. else
  11. echo 'Start jupyter'
  12. nohup jupyter notebook --no-browser --ip 0.0.0.0 --NotebookApp.token=zhangheng --port=8888 &
  13. fi
  14. result=`ps aux | grep -i "autossh -M 5000 -CNR 6000:localhost:22 root@121.196.215.154" | grep -v "grep" | wc -l`
  15. if [ $result -ge 1 ]
  16. then
  17. echo 'autossh 22 is running'
  18. else
  19. echo 'Start autossh 22'
  20. autossh -M 5000 -fCNR 6000:localhost:22 root@121.196.215.154
  21. fi
  22. result=`ps aux | grep -i "autossh -M 5001 -CNR 6001:localhost:8888 root@121.196.215.154" | grep -v "grep" | wc -l`
  23. if [ $result -ge 1 ]
  24. then
  25. echo 'autossh 8888 is running'
  26. else
  27. echo 'Start autossh 8888'
  28. autossh -M 5001 -fCNR 6001:localhost:8888 root@121.196.215.154
  29. fi

有几点需要注意

然后是实验室服务器把上面代码加入到开机自启动和定时任务,只需要在crontab就可以

  1. # crontab -e
  2. 0 */1 * * * /home/zsh_o/start_zsh.sh

最后重载contab

  1. sudo service crond reload

开启防火墙,由外对内的防火墙的端口都需要开开,autossh用-M制定的端口监听链接状态,这里我们为了省事直接开了多个

  1. sudo firewall-cmd --zone=public --add-port=5000-6000/tcp --permanent

重新载入配置使其生效

  1. sudo firewall-cmd --reload

公网服务器端很简单,首先阿里云服务器安全页面把防火墙的端口打开,然后做一下端口转发即可

  1. autossh -M 5012 -fCNL *:8022:localhost:6000 root@localhost
  2. autossh -M 5011 -fCNL *:8889:localhost:6001 root@localhost

最后,这种连接方式也会经常断线,而且短线频率很高,可能要改下什么配置就好了,但我暂时没找到。jupyter不怕短线,但ssh短线很要命,所以在ssh上跑的程序建议转到jupyter里面的terminal或者ssh中用tmux,这样只要实验室服务器不关机你的程序就还在跑,如果被关机或重启了,那没办法~~~

最后连接方式

  1. ssh: 121.196.215.154:8022
  2. jupyter: 121.196.215.154:8889

补充

后面遇到了一个问题,开机启动的时候是以root方式启动的,对于jupyter的使用和autossh来说是非常不好的,所以,要换成我个人用户来开机启动,方法很简单,首先删掉crontab里面的@reboot那行,然后单独在rc.local配置开机启动

  1. # sudo vim /etc/rc.d/rc.local
  2. su zsh_o -c "/home/zsh_o/start_zsh.sh"

jupyter

  1. jupyter notebook --no-browser --ip 0.0.0.0 --NotebookApp.token=realai --port=8889
  2. ssh -p 4716 jianfei@166.111.121.42 -f -N -L 172.16.36.124:8888:localhost:8889

ssh免密

把本地主机生成的密钥文件上传到远程服务器端的密钥文件里
在本地主机执行:

  1. ssh-keygen -t rsa
  2. ssh-copy-id root@121.196.215.154
  3. autossh -M 40012 -fCNR 7777:localhost:12111 root@121.196.215.154
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注