ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用iPhone搭一台免越狱的Git服务器:iSH+Alpine+OpenSSH实战

用iPhone搭一台免越狱的Git服务器:iSH+Alpine+OpenSSH实战 一部手机能不能变成一台真正的Git服务器答案是能。不用越狱不用换安卓也不用专门去开一台云主机只要在iPhone上装一个叫iSH的App就能把Alpine Linux跑起来然后在里面安装Git和OpenSSH做出一个能远程push/pull的仓库。很多人听到这里第一反应是会不会很卡是不是要折腾半天其实整个过程比想象中简单但确实也有不少坑。这篇文章不想讲太多高大上的概念就按我实际走过的流程来写从iSH安装到仓库配置再到电脑连接、数据推送最后是让服务稳定运行的几个关键操作。如果你也想有一台装在口袋里的Git服务器或者单纯想拿iPhone练手Linux下面的内容可以直接照着抄。1. 一部手机当Git服务器到底图什么先泼一盆冷水用iPhone当Git服务器性能上完全没法跟云服务器比也不是给几十人团队用的。但它的应用场景非常真实我自己就遇到过几次出差路上收到同事的紧急修改反馈手边没有电脑却想马上开一个仓库让同事把补丁推进来。平时在家已经关了NAS和电脑手机是唯一通电开机的设备。想要一个只给自己用的私密仓库又不想在每个项目上都掏钱买云盘。这些场景里一台能随时从口袋里掏出来、零耗电待机、免越狱运行的Git服务器确实比什么都方便。更重要的是隐私。放在云服务器上的代码本质上还是放在了别人的机器上。用iPhone当服务器代码始终留在自己的设备里不想给别人看的项目完全自控。对一些雏形方案、内部脚本、简历作品集这类东西这种随身保险箱式的仓库特别合适。和常见方案对比一下定位就更清楚了方案成本维护量可用性适合场景云服务器按月付费需要租机器、配安全组、续费高7x24小时在线团队协作、正式项目树莓派/NAS自建硬件投入需要固定IP或内网穿透维护系统高插电就能跑家庭实验室、长期服务iPhone iSH免费需要克服锁屏挂起问题手机亮着才稳定个人仓库、临时共享、学习Linux所以这篇教程的适用人群是个人开发者、学生、极客或者任何想在不额外花钱的前提下快速获得一个可访问Git服务的人。如果你的目标是生产环境的高可用Git服务器那还是老老实实买台云主机吧。2. iSH的运行机制免越狱的钥匙iSH刚火的时候很多人不理解iOS沙盒管理那么严格不能执行可执行文件凭什么iSH能跑Linux这里的关键在于它并没有去破解系统而是用了一种用户态模拟的思路。iOS上的App确实不能直接孵化任意进程也不能运行内核级的虚拟化但应用本身是有CPU执行权限的。iSH做的事情是把x86 Linux的程序翻译成ARM指令来执行同时把Linux程序的系统调用翻译成iOS系统调用。换句话说它像一个翻译官一样让Linux世界里的软件在iOS的沙盒里跑起来却不需要动系统底层。所以完全不需要越狱App Store搜iSH就能装。iSH内部默认跑的是Alpine Linux这是一个只有几兆基础包的超轻量发行版。Alpine用musl C库加BusyBox工具集对资源的占用极低非常适合iSH这种性能受限的环境。它的包管理器是apk安装git和openssh就是两条命令的事。不过模拟器终归是模拟器。iSH里跑程序会比原生ARM环境慢不少大型编译任务基本不用想但用来跑Git服务器、SSH服务、简单的Shell脚本完全是够用的。我在测试中同时开两个SSH会话做clone和push虽然能感觉到一点卡顿但没有出过错。另外要注意iSH有两个版本普通版模拟x86架构iSH Lite模拟RISC-V架构。普通版软件源里的包更多兼容性也更好所以这篇教程以普通版为例。下载App之后第一次启动会进入一个Alpine shell默认是root用户接下来就可以开始装了。3. 基础环境准备装iSH、换源、加Git和OpenSSH3.1 安装iSH并进入Alpine环境App Store直接搜iSH第一个就是。装好后打开会看到一个Shell界面等待几秒出现类似这样的提示/ #这就说明Alpine已经完全启动了。默认用户是root密码为空App使用的是沙盒内的虚拟文件系统不会影响手机系统。如果界面上没有出现Shell可以检查一下是否卡在初始化阶段。通常全新安装需要下载一定的根文件系统数据等半分钟到一分钟是正常的。如果一直没反应杀掉App重开一次就行。3.2 更换Alpine软件源默认软件源在国外不换源的话apk update可能要等很久装个包更是折磨。换源的方式是修改/etc/apk/repositories文件。在Shell里执行vi /etc/apk/repositories把里面的内容替换成国内镜像地址。以阿里云镜像为例普通iSH是x86架构所以用x86的Alpine路径https://mirrors.aliyun.com/alpine/v3.18/main/ https://mirrors.aliyun.com/alpine/v3.18/community/保存退出后执行apk update这个版本号要以iSH实际Alpine发行版本为准如果v3.18不存在可以先看默认源里的版本号把URL里的版本号替换掉就行。3.3 安装Git和OpenSSH换源完成后安装核心组件apk add git openssh等命令跑完验证一下版本git --version ssh -V看到版本号输出就说明安装成功。OpenSSH安装之后会生成一些默认的配置文件默认的host key也会在首次启动sshd时自动生成。注意iSH里没有systemd这类的进程管理所有服务都是直接在前台或后台手动启动。这里不需要执行rc-service sshd start而是直接用/usr/sbin/sshd不过先别急着启动我们要先把配置调整好再启动。3.4 顺手做基础配置时区和Git身份iSH里的系统时间默认继承自iOS理论上不会差太多但它的时区是UTC如果不改commit打出来的时间会和本地时间差8小时。为了后面提交记录好看一点先装上时区数据apk add tzdata cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime然后设置Git的全局身份信息这步经常有人漏掉git config --global user.name 你的昵称 git config --global user.email 你的邮箱这里设置的是服务端运行时的一些默认操作比如在服务端直接创建仓库或查看日志时用。日常提交时客户端会用自己的身份信息服务端身份只影响服务端直连操作。4. 配置SSH服务端别让root裸奔创建专用用户一开始我也图省事直接用root跑ssh。但后来发现Git仓库接收推送时文件归属全在root名下一旦哪天想切到普通用户权限会很难收拾。更稳妥的做法是在iPhone上创建一个专用用户git专门管理仓库文件。4.1 创建git用户并规划目录在Alpine里创建用户用adduseradduser -D git-D表示不设置密码因为后面我们只用密钥登录。Alpine的adduser默认会把用户home目录建在/home/gitShell用的是/bin/sh。可以顺手验证一下id git接下来规划仓库的存放目录。我的习惯是把所有裸仓库放在/home/git/repos下目录归属给git用户mkdir -p /home/git/repos chown -R git:git /home/git4.2 修改sshd_config编辑/etc/ssh/sshd_config至少要看这几个关键项vi /etc/ssh/sshd_config推荐配置PermitRootLogin no PubkeyAuthentication yes PasswordAuthentication no AuthorizedKeysFile .ssh/authorized_keys Port 22PermitRootLogin no彻底关闭root的SSH登录就算密码对了也进不来。PasswordAuthentication no关掉密码登录只允许密钥登录这样既安全后面clone的时候也不需要输密码。提示如果你刚开始配置想先试密码登录看链路通不通可以临时把PasswordAuthentication设为yes等密钥配好再改回no。安全起见最终一定要关掉密码登录。4.3 客户端生成密钥并上传到git用户在电脑上如果还没有密钥打开终端执行ssh-keygen -t ed25519 -C your_emailexample.com一路回车生成即可。公钥默认在~/.ssh/id_ed25519.pub。用ssh-copy-id或手动复制的方式把它放到iPhone上ssh-copy-id git192.168.1.10如果你的iSH还没来得及启动sshd可以先启动一次再执行/usr/sbin/sshd如果你手头有iPhone的控制权直接在iSH里手动建/home/git/.ssh/authorized_keys然后把公钥粘贴进去也完全可行mkdir -p /home/git/.ssh vi /home/git/.ssh/authorized_keys贴进去后给目录和文件设置正确的权限这一步很容易出错chown -R git:git /home/git/.ssh chmod 700 /home/git/.ssh chmod 600 /home/git/.ssh/authorized_keysSSH对用户home目录、.ssh目录和authorized_keys文件的权限要求很严格任何一级权限过宽服务器都会直接拒绝接受密钥。启动sshd后检查一下监听是否正常ss -tlnp | grep sshd能看到类似0.0.0.0:22的监听就对了。iSH默认没有ss命令的话用netstat -tlnp | grep sshd也行。5. 创建裸仓库并从电脑完成第一次推送5.1 git init --bare 和普通git init的区别普通仓库是你自己干活的工作目录里面能看到源代码、.git文件夹。服务器上不需要源文件的工作树只需要元数据、对象数据库、引用、hooks这些内容所以要用裸仓库也就是执行cd /home/git/repos git init --bare myproject.git chown -R git:git myproject.git执行完后目录里会是一堆Git内部的目录结构比如branches、hooks、objects、refs等没有实际的文件快照。5.2 从电脑克隆仓库假设iPhone的局域网IP是192.168.1.10怎么查后面会说到在电脑上的命令就是git clone ssh://git192.168.1.10:22/home/git/repos/myproject.git注意这里的路径是绝对路径。如果用git clone git192.168.1.10:myproject.git这种简写Git会把:后面的部分解释为相对路径而且默认是用户home目录下的路径。两种写法不统一时经常会踩坑。SSH密钥配置正确的话执行后会直接clone成功不会有密码提示。假如看到Permission denied (publickey)多半是authorized_keys权限问题或者密钥没贴对。5.3 一次完整的提交推送流程进入项目目录随便造一个文件然后执行完整的Git流程cd myproject echo # My First iPhone Git Repo README.md git add README.md git commit -m init project git push origin master如果一切正常push后iSH端会收到对象数据仓库的refs/heads/master也会更新。此时再换一台电脑用同样的SSH地址clone就能拿到刚刚推上去的文件了。5.4 看到的git警告和正常输出第一次用iSH上的Git服务器时很多人在push时会看到一堆以remote:开头的输出来自服务端hook。如果配置了git用户但没有设置服务端的全局身份偶尔会有Please tell me who you are之类的警告。为了避免这种问题前面章节里设置git config --global user.name和user.email的操作才显得必要。输出里如果出现warning: SECURITY: no bin directory found之类通常是服务端用户的home目录下没有bin目录不会影响仓库功能。真正要关注的是error:开头的输出那些才是实际问题。6. 让服务稳定运行锁屏、后台、IP漂移这是整个教程里最容易被忽略的部分。很多人按前面的步骤搭好了仓库刚想跟同事说来clone我的iPhone结果手机一亮屏或者锁屏三分钟服务就彻底连不上了。原因很简单iOS为了省电会在App进入后台后挂起进程iSH一旦被挂起里面的sshd也一起被冻结。6.1 锁屏或切后台导致服务失联iPhone锁屏后一般几秒内App就会被系统挂起。如果你只是切到其他AppiSH在后台最多撑一小会儿也会被冻结。表现就是远程SSH连接超时或者连接已经建立但卡住不动。解决办法最直接的就是让iSH一直保持前台运行并且不让它锁屏。在iPhone的设置 - 显示与亮度 - 自动锁定里选择永不。这样只要手机亮着iSH就能一直跑sshd也就一直能连。代价是电量消耗会明显增加所以最好同时插上充电器。6.2 防止误触和意外退出的引导式访问就算设了永不自动锁定你也不能保证手在口袋里不会按到电源键或者Home键一锁屏服务就断了。这时候可以借助iOS的引导式访问功能把iSH钉在前台。开启方法在设置 - 辅助功能 - 引导式访问里打开开关然后回到iSH界面快速连按三次电源键或侧边按钮iPhone会进入引导式访问模式。这个模式下系统会锁定当前App屏蔽误触而且因为配合了永不自动锁定就可以在手机不锁屏的情况下长时间保持服务在线。注意开启引导式访问后如果你想退出iSH界面需要连按三次侧边按钮并在密码界面退出或者用面容ID/指纹确认。新手第一次开这个功能时容易卡住建议先自己练习一次再正式使用。6.3 IP地址老变怎么办iPhone走Wi-Fi时每次重连路由器拿到的IP可能是随机的。如果你在日常使用中经常发现连不上先查一下iPhone当前的IP在iSH里执行ifconfig或者直接ip addreth0那段的inet 192.168.x.x就是当前IP。这个IP会变解决方法是在路由器管理后台找到iPhone的MAC地址为它设置静态DHCP分配让路由器每次都给这台iPhone分配同一个IP。如果你用的公网访问方案还要考虑端口转发和动态域名这个在进阶章节再说。7. 进阶玩法多仓库、自动部署、内网穿透与备份策略基础版本跑通之后你会发现这东西可以越玩越顺。我整理了几个自己用得比较多的进阶方向。7.1 多仓库管理和目录规划如果以后项目变多建议在/home/git/repos下按项目名分开建裸仓库cd /home/git/repos git init --bare project-a.git git init --bare project-b.git每次克隆时地址就是ssh://git192.168.1.10:22/home/git/repos/project-a.git。在客户端也可以通过配置SSH的别名来简化命令比如在~/.ssh/config里加上Host iphone-git HostName 192.168.1.10 User git Port 22 IdentityFile ~/.ssh/id_ed25519之后克隆git clone ssh://iphone-git/home/git/repos/project-a.git这样IP变了也只需要改HostName一行。7.2 用Git hooks自动部署如果你希望在push代码后自动把文件部署到某个目录而不必手动拉取可以写一个post-receive脚本vi /home/git/repos/project-a.git/hooks/post-receive内容示例#!/bin/sh GIT_WORK_TREE/home/git/www/project-a git checkout -f chown -R git:git /home/git/www/project-a然后给脚本执行权限chmod x /home/git/repos/project-a.git/hooks/post-receive这样每次push后服务端会自动把最新文件同步到/home/git/www/project-a。对于个人博客、静态页面这类项目非常方便。7.3 内网穿透或公网端口转发如果想让不在同一局域网的人也能访问你的iPhone Git服务器需要一台有公网IP的VPS做SSH反向隧道转发或者使用frp这类内网穿透工具。基本思路是把iPhone上sshd的22端口映射到VPS的公网端口上。这样外面的人访问VPSIP就能通过隧道连到你的iPhone。这步涉及安全加固建议至少做到只开放密钥登录、不暴露22默认端口、给VPS侧加白名单或fail2ban。手机端长期开放公网访问并不推荐临时给同事推个代码用完把隧道关掉即可。7.4 备份iSH数据iSH的文件系统全部保存在App自己的沙盒里也就是说如果你把iSH从手机上删除仓库数据会一起消失。所以重要的仓库务必定期备份。最简单的备份方式就是直接克隆一份到电脑或云盘git clone --bare ssh://git192.168.1.10:22/home/git/repos/project-a.git project-a-backup.git也可以定期把/home/git/repos整个目录用tar打包然后通过scp拷到电脑上。记住任何没有冗余方案的数据都是有风险的别让手机成为你的唯一副本。8. 我在搭建过程中踩过的坑和一些体会这一路试下来最大的坑其实是以为配好就能一直用。第一次搭完我开心地把手机放进口袋结果到了楼下用电脑连的时候怎么都连不上。回到室内一看屏幕早锁了。后来才悟到iSH服务器的存活条件跟普通服务器完全不同它依赖iOS的前台状态。理解了这一点后面所有的锁屏设置和引导式访问都顺理成章。还有一个容易被忽略的点iSH里调整过sshd_config后要重启sshd才生效。没有systemd最简单的做法是找到进程ID直接杀掉再启动pkill sshd /usr/sbin/sshd如果改错了配置导致sshd起不来可以先在前台运行看报错信息/usr/sbin/sshd -d这会把详细调试日志打到终端上排查问题比看日志文件直观得多。另外iSH对Wi-Fi网络的依赖性很强。iPhone用的是普通Wi-Fi热点如果热点本身开启了客户端隔离两个设备之间是互通的但公网访问能力就可能受限。这种场景下优先考虑让手机和电脑连接同一个路由器。最后说点实在的体会用iPhone当Git服务器肯定不会成为生产环境的主力方案但作为个人项目、临时共享、学习Linux环境的一块试验田它真的很有意思。特别是当你从电脑上敲下git push然后随手从口袋里掏出手机打开仓库目录看到刚刚提交的代码已经静静躺在里面的时候那种我自己搭了一个服务器的实感不是云服务器能给的。更别说整个过程一分钱没花还免了越狱。只要心里清楚它的边界它就是个非常趁手的小玩具。
返回列表