**约定:**下文以local$
表示本地主机,remote_{数字}$
表示远程主机,数字用以区别不同的远程主机,本地主机可以为linux也可以为windows,但是远程主机此处假定只为linux。
一、免密登录
Step 1: 确认本地是否已经生成id_rsa
与id_rsa.pub
这两个文件,若有这两个文件跳到Step 3;
note: ubuntu查看
/home/{UserName}/.ssh/
;Win10查看路径为C:\Users\{UserName}\.ssh
。
Step 2: 在PowerShell中运行ssh-keygen -t rsa -C "{备注}"
生成id_rsa
与id_rsa.pub
这两个文件;
note: 默认存放地址:ubuntu为
/home/{UserName}/.ssh/
;Win10为C:\Users\{UserName}\.ssh
。
Step 3: 将id_rsa.pub
中的内容添加到远程主机的/home/{remote_username}/.ssh/authorized_keys
文件未尾;
- 本地主机为ubuntu可以运行:
local$ ssh-copy-id user@remote_ip
- 本地主机为ubuntu与win10通用的方式:
# win10 在PowerShell中运行 ubuntu 在终端中运行
local$ scp .ssh/id_rsa.pub user@remote_id:/home/{
remote_UserNmae}/.ssh/key_temp
local$ ssh user@remote_ip 'mkdir -p .ssh && cat .ssh/key_temp >> .ssh/authorized_keys && rm .ssh/key_temp'
上面第1行命令是在本地主机上将本地主机的
id_rsa_pub
拷到远程主机的.ssh
目录下,并重命名为key_temp
;
上面第2行命令是在本地主机上通过SSH远程访问(此时还需要输入密码)远程主机,并在远程主机上利用cat
命令将key_temp
中的内容追加到``authorized_keys文件未尾,也即将本地主机的公开密钥追加到远程主机authorized_keys文件中。追加完后,删除临时文件key_temp
。
操作完后,我们执行以下命令,不再需要输入远程主机的登录密码即可进行远程访问该主机。
local$ ssh user@remote_id
希望有厉害的人将以上步骤写成一个bat或shell脚本,一键部署。
二、配置别名
每次ssh登录都要输入ssh user@remote_id
,时间一长我们很容易忘记远程主机的ip地址,配置别名可以让我们用一个容易记住的语义名称(例如为remote_name
)与远程主机关联,我们可以直接ssh {remote_name}
来访问。
Host remote_name # 将remote_name替换成你觉得很容易与该远程主机关联的语义名称
HostName remote_ip
User remote_UserName
Port port # 这一行可以不填,不填默认为22
IdentityFile {
本机存储私钥的地址,最好用绝对地址}/id_rsa # 这一行可以不用, vs code配置ssh远程无密访问是加了这一行的
三、反向隧道实现内网穿透
2023-4-20补充:在用ssh反向隧道之前,是一直尝试用frp,一直没有成功。刚才我又操作了下frp,发现可以。可能还是和root有关。在root超级用户下可以。如果想省事,直接用frp挺简单的。
3.1 ssh普通访问的几种组合
假定我们有两个主机A(公网)与B(内网),主要信息如下表所示:
主机名 | IP | 超级用户 | 普通User |
---|---|---|---|
A | IP_A | root | user_A |
B | IP_B | root | user_B |
用普通的ssh,B可以访问A,A不能访问B,可以通过以下命令在B上访问A:
user_B$ ssh user_A@IP_A # B主机上的普通用户user_B访问A主机上的普通用户user_A
或
user_B$ ssh root@IP_A # B主机上的普通用户user_B访问A主机上的超级用户root
或
root@B$ ssh user_A@IP_A # B主机上的超级用户root访问A主机上的普通用户user_A
或
root@B$ ssh root@IP_A # B主机上的超级用户root访问A主机上的超级用户root
note: 允许以ssh访问主机上的超级用户需要在
/etc/ssh/sshd_config
文件中,将PermitRootLogin
置为yes
。具体参考Ubuntu 启用 root 账户、启用密码登录、启用Key登录。
3.2 ssh IP
的隐含意思——成功的关键
user_B$ ssh IP_A
等价为:
user_B$ ssh user_B@IP_A
看到没有,这是一个BUG,当A主机上没有一个与user_B同名的用户,这行命令怎么都不可能ssh成功。
如果A与B主机都激活了root,并且设置了相应的ssh配置文件,那么在B主机上以root用户输入ssh IP_A
是有效的,它最终连到A主机的超级用户root。
root@B$ ssh IP_A
等价为:
root@B$ ssh root@IP_A
激活root,在普通用户终端输入以下命令,按提示两次输入要设置的root密码就完成了激活root超级用户:
sudo passwd root
是造成我内网穿透失败的原因,这个会在后面提。先记住这个BUG。
3.3 正式开始内网穿透
前提:
- 具有公网IP的主机激活了超级用户root;
- 要内网穿透的内部主机激活了超级用户root;
- 两台主机在超级用户下生成ssh-key并设置了免密登录(参照第一节);
- 两台主机的
/etc/ssh/sshd_config
以下字段按以方式设置:
PermitRootLogin yes
GatewayPorts yes
设置完重启sshd:
systemctl restart sshd
3.3.1 在公网主机A的root用户终端下,开放端口port_x
相关指令参照 Linux查看防火墙状态,查看开放端口。
3.3.2 在要内网穿透的内部主机B的root用户终端上执行:
ssh -fCNR port_x:localhost:22 root@IP_A
3.3.3 在任意一台能访问公网的主机C上(不限制哪个用户)上执行:
ssh -p port_x root@IP_A
如果进入内部主机B的root用户,则说明内穿成功。
如果失败请回头检查自己的步骤是否按照本博客来,慢慢来。
四、ssh反向隧道实现外网访问内网jupyter notebook
参考ubuntu安装jupyter 并设置远程访问 或Ubuntu下开启jupyter远程开启juyter远程访问。
在同一局域网内访问,验证设置是否成功。
先在内网主机上启动jupyter notebook,然后运行:
ssh -fCNR relay_port:localhost:jupyter_port root@IP_A
上面的relay_port
为公网主机A上用于转发内网jupyter notebook的端口,jupyter_port
为内网jupyter notebook的端口。
完成后,我们可以在任意能访问公网主机A的电脑上的浏览器中输入https:IP_A:relay_port
便可访问内网主机上的jupyter notebook,
未完待续。。。