在家用機上搭建 Git https 服務器


今天主要敘述在家里台式機的虛擬機上搭建支持 https 的 ubuntu git 服務器。

   

實際上,從一個用戶請求家里 git 服務器代碼,最終完成代碼的傳輸,主要是通過以下的過程:

   

首先,從外界尋找到連接上互聯網的家里的路由器,由路由器發送請求到虛擬機的 host,由 host 發送到虛擬機,由虛擬機的 apache 服務器將 https 請求轉化為 git 數據請求發送給 git 服務程序,git 服務器程序拿到數據以后原路返還,下面一點一點的將這個過程說清楚。

   

第一步:從外界找到家里的路由器

由於家里的網絡是動態撥號,沒有固定 ip,所以想實現這個需求,就必須使用動態 DNS

可以使用花生殼的 DDNS,這一步每一個路由器都不同,所以不再詳述。

   

   

第二步:從路由器發送到 host

發送到 host 的過程主要用到路由器的端口映射功能,並且需要配置 host 的防火牆以保證入站是通暢的。

   

  1. 規划好路由器對外暴露的端口和主機暴露的端口,以及主機的局域網 ip

    路由器對外暴露的端口,最后我們會以 https://XXXX.YYYYY.CCCCC:路由器對外端口/XX的形式訪問到內部服務,這里假設為 10086

    Host 暴露的接口,路由器會將請求發送給這個端口,以提供服務,這里假設為 56789。

    主機的局域網 ip 用來配置端口映射時,讓路由器知道應該將請求發送到哪個機器去,這里假設為 192.168.3.50

       

  2. 配置主機 ip

    有兩個方法,一個是主機直接在 ip 設置里面手動配置,但是這種配制方法不一定能完全消除 ip 沖突(雖然家庭局域網的 ip 沖突不常見),所以可以利用路由器的 ip 分配功能,每個路由器不一樣,在我的路由器界面如下:

    為特定 mac 地址分配了特定的 ip

       

  3. 配置路由器到主機的端口映射

    這一步每個路由器的界面都不一樣,但是配置的原理是共通的

       

    我使用的是 netgear orbi,其配置界面如下(高級——高級設置——端口映射/端口觸發——添加自定義服務),外部端口組指的是路由器對外開放的端口,內部端口組是局域網提供服務主機的端口。

    1. 為主機添加防火牆規則

    進入以上界面,點擊"入站規則"后,再點擊右側欄的"新建規則",出現以下界面:

       

       

       

       

    至此,第二步配置完畢

       

第三步:從 host 轉發到虛擬機

這一步需要配置虛擬機 NAT 模式的端口轉發,並且設置虛擬機的 ip 地址,還要配置虛擬機 apache 服務器 https git 服務的端口

   

  1. 規划虛擬機 ip、服務端口、網段等

    這里假設子網 ip 為 192.168.158.0,掩碼是 255.255.255.0

    虛擬機 ip 是 192.168.158.20

    給虛擬機分配的 git 服務端口是 5000

  2. 設置虛擬機軟件

    vmware 為例(其他虛擬機軟件也有類似功能),點擊"編輯"——"虛擬網絡編輯器",按照如下界面配置

       

       

    之所以 dhcp 從 128 開始,是因為保證 .20 這個地址沒有自動分配到別的虛擬機去。

  3. 配置主機虛擬機軟件的端口轉發規則

       

    注意這里的網關 ip,下面要用到

       

  4. 設置虛擬機

    開啟虛擬機,這里以 ubuntu 16.04 LTS 英文版版本為例,其他版本大同小異

    "system settings"——"network"

       

    注意,這里的 DNS Server 和上面的網關 ip 設置一樣,也可以設置為家里路由器的地址,比如 192.168.3.1

       

    然后關閉並打開下圖的開關,重新讓虛擬機連一下網,使之分配到新的 ip 去

       

    嘗試在虛擬機里連接一下網絡,測試一下。

       

    至此,第三步已經全部完畢。

       

    關於第三步,實際上可以使用虛擬機的橋接模式,使之成為局域網中的一個獨立機器,這樣,直接從路由器就可以給虛擬機分配一個 ip(詳見步驟二),並且配置端口轉發。這種方法省去了配置 host 防火牆的步驟,容易維護(不用修改虛擬機 NAT 規則,也不用在虛擬機里面配置靜態 ip,直接使用路由器的預留 ip,虛擬機使用 dhcp 獲得就可以了)

       

    但是我這里之所以使用了 NAT 模式,是因為我上一個路由器這樣做有 bug(吐槽榮耀 pro……),在如此配置之后,路由器只能識別虛擬機的網卡,卻不能識別主機的網卡,導致分配到主機的其他服務全都用不了了,所以只能使用 NAT 模式,如果路由器能支持識別橋接的虛擬機,那當然要用橋接。我這里就不改了,算是提供一個橋接不行的時候的思路。

   

第四步:從 apache 服務器將 https 請求轉化為 git 數據請求發送給數據程序

這一步需要配置 apache 的服務器,開啟 https 支持,開啟 git 支持,增加 Git 賬戶名和密碼。

   

進入虛擬機:

  1. 安裝 apache2 的相關工具

    sudo apt-get install apache2 apache2-utils openssl

       

  2. Create git repository folder

    創建一個用於存儲代碼倉庫的文件夾,后面配置服務器主機的時候會用到

    cd /opt

    sudo mkdir git

    sudo chown youraccountname:www-data git

       

    之所以將 owner 變為當前登錄服務器的用戶名,是因為這樣好管理,后來管理代碼庫時,用不着每一次都 sudo

  3. 創建 CA 證書,這里以 self signed 為例

    這里創建的是自己簽名的 CA 證書,實際上網上也有很多免費的 CA 證書,比如騰訊雲的。之所以這里選擇自己簽名的,是因為大多數情況下這種方法夠用(畢竟是自己的服務器,幾乎只有自己用),不過,自己簽名的 CA 證書在 git clone 的時候可能遇到問題,后面步驟會有解決方案。

    我們假設把證書存儲在了 /opt/sites_conf 目錄中

       

    sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /opt/sites_conf/apache.key -out /opt/sites_conf/apache.crt

       

    運行以后,填寫方法大概如下:

    Country Name (2 letter code) [AU]:CN

    State or Province Name (full name) [Some-State]:Beijing

    Locality Name (eg, city) []:Beijing

    Organization Name (eg, company) [Internet Widgits Pty Ltd]:這里隨便填

    Organizational Unit Name (eg, section) []:這里隨便填

    Common Name (e.g. server FQDN or YOUR name) []:這里一定要填寫個人服務器的域名,在本例中,就是 XXXX.YYYYY.CCCCC,如果不一致,后面的 ssl 驗證會失敗

    Email Address []:隨便填

       

  4. Enable apache modules

    sudo a2enmod cgi alias env rewrite

       

  5. Listen port 5000

    sudo gedit /etc/apache2/ports.conf

       

    在這個文件里面加入一行:

    Listen 5000

    然后保存退出

  6. Config virtual machine

    cd /etc/apache2/sites-available

    創建新的配置文件並且填入內容:

    sudo gedit git_server.conf

    填入如下內容

    <VirtualHost *:5000>

    ServerAdmin you@example.com

    ServerName RukaCode

    SetEnv GIT_PROJECT_ROOT /opt/git

    SetEnv GIT_HTTP_EXPORT_ALL

    SSLEngine on

    SSLCertificateFile /opt/sites_conf/apache.crt

    SSLCertificateKeyFile /opt/sites_conf/apache.key

       

    DocumentRoot /opt/git

       

    <Files "git-http-backend">

    AuthType Basic

    AuthName "Git Access"

    AuthUserFile /opt/sites_conf/htpasswd

    Require valid-user

    Order deny,allow

    Deny from env=AUTHREQUIRED

    Satisfy any

    </Files>

       

    <Location />

    AuthType Basic

    AuthName "Git Repositories"

    AuthUserFile /opt/sites_conf/htpasswd

    Require valid-user

    Order allow,deny

    Allow from all

    </Location>

       

    ScriptAlias / /usr/lib/git-core/git-http-backend/

     

    RewriteEngine On

    RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]

    RewriteCond %{REQUEST_URI} /git-receive-pack$

    RewriteRule ^/ - [E=AUTHREQUIRED]

    </VirtualHost>

       

    這里的配置阻止了 invalid user 的 clone,並且也阻止了 http 的訪問。如果不需要阻止 invalid user 的 clone(比如開源項目),那么可以將 <Location> 那一段去掉。此時 invalid user 可以 clone 但是不能 push。

     

    接着,需要將此配置 link 到 enable 文件夾里面去

    cd ../sites-enabled

    sudo ln -s ../sites-available/git_server.conf .
     

  7. 啟動虛擬機

    sudo apachectl start

    或者如果已經啟動了虛擬機的話,那就

    sudo apachectl restart

       

  8. /opt/git 里面創建需要的代碼庫

    cd /opt/git

    mkdir test_repo.git

    cd test_repo.git

    git init --bare

    sudo chgrp www-data -R .

       

  9. /opt/sites_conf 里面創建用戶名、密碼文件

    htpasswd -c /opt/sites_conf/htpasswd yourusername

       

    這里的文件路徑一定要和上面配置文件里面的

    AuthUserFile /opt/sites_conf/htpasswd

    對應

       

至此,服務器端已經配置完畢。接下來還需要有兩個步驟,一個步驟是創建一個 git 代碼庫,並且 push 到服務器上去,因為此時創建的 test_repo.git 是空的,其他用戶 clone 下來是一個空的 repo,其 HEAD、upstream 等都沒有設置好,所以此步驟解決這個問題。還有一個步驟,是將服務器的 self signed 的 CA 證書添加到 git 的信任 sites 里面,這一步主要是因為我們的證書是自簽名的,因此 git 在 clone 的時候驗證其合法性時,會直接 deny 掉這個請求,需要將其添加到信任證書里。

   

  1. 在任意機器上,創建一個本地 repo,假設這個 repo 在 ~/my_test_repo 文件夾下

    mkdir ~/my_test_repo

    cd my_test_repo

    git init

    touch README.txt

    git add .

    git commit -m 'add read me file'

  2. 添加服務器證書到 git 信任列表里

    git 信任列表由 http.sslCAInfo 來控制,設置這個值為一個文件,git 就會在這個文件里面查找是否是一個受信任的主機,所以我們要做的就是將服務器的 crt 文件內容復制到這里的文件里面。

       

    要顯示服務器的 crt 文件內容,最簡單的就是使用瀏覽器,但是由於我們並沒有給 git 服務器配置網頁以供瀏覽(可以用 Gitweb 實現),所以瀏覽器如果直接鍵入網址的話會 deny

       

    那么只好用命令行,輸入以下命令:

    openssl s_client -showcerts -connect yoursitedomain:yoursiteport|sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

    注意,要將 yoursitedomain:yoursiteport 轉化為你的 git 服務器的網址和端口,回到第一步可以看到,這里的例子為 XXXX.YYYYY.CCCCC:10086

    如果連接沒問題,就會看到如下的信息

    -----BEGIN CERTIFICATE-----

    MIIEGTCCAwGgAwIBAgIJAISj2sI7kbd3MA0GCSqGSIb3DQEBCwUAMIGiMQswCQYD

    VQQGEwJDTjEQMA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEVMBMG

    A1UECgwMU25pcGVyIFN3b3JkMRUwEwYDVQQLDAxTbmlwZXIgU3dvcmQxHDAaBgNV

    BAMME3NuaXBlcnN3b3JkLnFpY3AuaW8xIzAhBgkqhkiG9w0BCQEWFGNsY3ZhbXBp

    cmVAZ21haWwuY29tMB4XDTE3MDExNTEzMzgzMFoXDTE4MDExNTEzMzgzMFowgaIx

    CzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdCZWlqaW5n

    MRUwEwYDVQQKDAxTbmlwZXIgU3dvcmQxFTATBgNVBAsMDFNuaXBlciBTd29yZDEc

    MBoGA1UEAwwTc25pcGVyc3dvcmQucWljcC5pbzEjMCEGCSqGSIb3DQEJARYUY2xj

    dmFtcGlyZUBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB

    AQDmrlk2Y3k9OJOg3YPOkJf2f1QcvYwsiRcdSemtWAqNGyXVdGlrXPQNpRgDfOPs

    Qmb5V/ELX6Gl+0rSiKS7N+tKlmru8oJgGvADGUTTU9gMDeGR5ztUmqhik57C3E+V

    AL+Oq2TaJqWoseDB1KdF4/4p3PmFDfeGg+vdWEaSihWG/p2lfRPjH+hr9mH/R2Pn

    ZO7Y+TvNevU8pBVmdhh88nHYorIZ0m1/Zk11ADyVuCBVF3ygt4QYv7Lb/N67SiyT

    uqlfifEZR+CEVfaBkaIqhC21YG6NtnQ40LFa2uqr7Hbx2xz30yYrUmlhcHtEop5w

    ZxdsM7iXvt4aYOyOjhljZ4gXAgMBAAGjUDBOMB0GA1UdDgQWBBTbbonTeEU+JIls

    axkFePsbFVqsjzAfBgNVHSMEGDAWgBTbbonTeEU+JIlsaxkFePsbFVqsjzAMBgNV

    HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQARaDGHn9/9RT0Qk0AcztRMyjrU

    KOcxgad5SAGmG/8BNJR5zEmgeUm+Az31qKBT1m2JNy16cD1+3ulNTKVkZ7j8judt

    EZiUEzsJxgZ4seQ5eQIeORS1IKuadyQevnjMvubzPOmDzOt4DdQNuHcq+Xmv4XP/

    2afrtYseGTWJl66qH2ssQ9ilkg8ju7G/7MGiFpF+pBve3tWyvcltsmgcDEcJotJq

    BY4uqrVAko+28aPhwVyR63CIk52G7WwJcoJ1sCm0SCzbHbTTNJLqRCbuYBWgXCrb

    kyHbS7ACz8onV219sghBQpsyHjVsIg6nFem9pufa1xbwkI1R3wMEfCqZZZM1

    -----END CERTIFICATE-----

       

    將這個信息復制到一個文件里(注意,--BEGIN CERTIFICATE— 和 –END CERTIFICATE— 也要一並復制),比如 ~/git_trust_ca.crt,並保存

       

    然后設置:

    git config --global http.sslCAInfo '/home/xxxxxx/git_trust_ca.crt'

       

  3. 第1小步已經創建好了 repo,這一步將其 up 到服務器上去:

    git remote add origin https://XXXX.YYYYY.CCCCC:10086/test_repo.git

    git push origin master

       

    此時出現輸入用戶名和密碼的地方,直接輸入即可 push

       

至此,git 個人服務器已經全部搭建完畢,實際上接下來還可以給 git 服務器增加 web 界面,便於管理項目等


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM