[分享] SSH和Git共享22端口,适用于docker或者frp转发等
先说下我的使用场景:
- 我有一台跑在腾讯云上的
VPS
,就是此博客系统所在的机器,这台机器是有公网IP的 - 在我家里的内网,有一台4核16G的小型服务器,没有公网IP,运行
Proxmox VE
虚拟了各种服务,其中包括Gitea
- 我通过
frp
转发暴露内网的Gitea
到公网 - 在这之前我一直使用
HTTP
协议上传或者下载代码,现在觉得太麻烦想用SSH
协议
如果你跟我的场景类型,此文很适合你,如果你是同一台机器上docker
和宿主机
之间22端口共享问题,文末官方文档更适合你。
本文也是参考了文末官方文档的实现,但是有部分不太一样。
安装Gitea
参考官方从二进制安装安装,同时配置service
运行,这里不多说。
但是建议使用git
用户安装,这样运行目录就是 /home/git/gitea
,后文会按照这个路径来说明。
配置frp转发
在frpc.ini
添加如下配置,分别转发HTTP
协议和SSH
协议:
[home.gitea]
type = http
local_ip = 192.168.1.103
local_port = 3000
custom_domains = git.fengqi.me
use_compression = true
[home.gitea.ssh]
type = tcp
local_ip = 192.168.1.103
local_port = 22
remote_port = 44322
use_compression = false
创建新的 SSH 密钥对
在有公网IP的机器上执行命令:
sudo -u git ssh-keygen -t ed25519 -C "Gitea Host Key"
连续回车,使用默认的文件名,无密码,生成完成后,复制 ~/.ssh/id_ed25519.pub
的内容,添加到内网机器的/home/git/.ssh/authorized_keys
内。
注:如果您使用的是不支持 Ed25519 算法的旧系统,请使用以下命令:
sudo -u git ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
可以把4096
改完3072
或者2048
,降低加密强度。
如果你的公网机器上没有git
用户,需要执行一下命令创建:
sudo adduser --disabled-login --gecos 'Gitea' git
创建 gitea
文件
在有公网IP的机器上创建/home/git/gitea
文件,并写入如下内容:
ssh -p 44322 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
里面的端口
和ip
改为你实际运行Gitea
的机器的,并执行 chmod +x /home/git/gitea
给予可执行权限。
同步SSH公钥
复制内网运行Gitea机器上/home/git/.ssh/authorized_keys
的全部command="/home/git/gitea
开头的内容,添加到有公网IP机器的/home/git/.ssh/authorized_keys
内,注意不要覆盖你原有的内容,是新增。
这里需要注意的是,官方的文档docker是和宿主机共享一份authorized_keys
文件,如果在Gitea的Web界面添加SSH公钥,宿主机也能使用最新的。
但是本文的方案是分离的,所以需要自己想办法同步公网机器和内网Gitea机器的authorized_keys
文件,否则新增的用户SSH
认证会失败。
如果你是和我一样自用,不对外公开,那手动处理就行了。
测试
理论上这个时候你已经可以使用git
协议上传和下载代码了
如果你碰到如下报错:
ssh: connect to host 127.0.0.1 port 44322: Connection refused
可以尝试在有公网IP的机器上执行 ssh -p 44322 git@127.0.0.1
来确认frp转发是否配置正常
如果你碰到如下报错:
Gitea: Internal Server Error
fatal: Could not read from remote repository.
请确认在有公网IP上生成的密钥对的公钥是否添加到内网机器上
如果你碰到如下报错:
Permission denied (publickey,password).
fatal: Could not read from remote repository.
请确认内网机器和有公网IP的机器的authorized_keys
内容是否同步,留意key-1,key-2,key-3。。。
的对应是否正确
原理:
- 生成的新密钥对是用于公网机器到内网机器的
SSH
认证,走的是frp开辟出来的通道 - 公网机器会通过这个通道把
Git
的SSH
命令就是SSH_ORIGINAL_COMMAND
转发到内网 - 需要同步公网和Gitea的key的原因是,git操作首先是需要和公网IP的机器进行SSH认证,通过后才能触发脚本转发到frp开辟的通道,所以其实会有两次SSH认证