使用frp實現內網穿透

如今辦理寬帶的時候,運營商都不會給你分配公網靜態ip,這致使的問題就是若是你想讓外部網絡訪問家裏局域網內的某臺設備,你不能使用通常路由器都自帶的端口映射(虛擬服務器)來簡單的讓外部網絡成功訪問到。在運營商動態分配ip的時候,若是動態分配到的ip是公網ip,那麼可使用一些收費的DDNS動態域名解析服務來訪問內網中的web服務,這時候路由器的端口映射也是須要配置的。若是動態分配到的ip不是公網ip,那麼DDNS也不會靈光了。咱們須要完全一點的方案,那就是內網穿透,即經過一臺具備公網靜態ip的電腦(服務器,vps等),來反向代理內網中的機器。python

怎麼樣來理解經過反向代理穿透到內網呢,首先咱們須要在具備公網靜態ip的服務端,安裝一個代理服務(例如本文將要提到的frp的服務端frps),而後在內網的設備上安裝此代理服務的客戶端,服務端跟客戶端都做爲後臺服務啓動運行(服務端首先啓動運行),客戶端鏈接到代理服務的端口,此時咱們的服務端做爲反向代理服務器已經能夠接受來自互聯網的請求了,並可以把請求轉發到客戶端上設置好的相應端口(服務,例如web)上。簡而言之,如今咱們能夠從外部網絡訪問內網中的某些設置好的設備了。linux

前些日子,我想要在上班的時候也能訪問家裏的刷好openwrt的路由器的設置界面及ssh服務,因此經過google,最終我決定使用frp這個開源軟件,下面是github上的項目主頁:
github.com/fatedier/fr…
更多配置請訪問項目主頁自行研究。git

折騰過程記錄:

前提:

  • 一臺有公網靜態ip的設備(服務器,vps,openwrt路由器...)。
  • 代理tcp協議不須要域名,代理http,https協議必需要準備域名。

服務端配置

首先從此處找到適合本身系統架構的編譯好的軟件包,點擊右鍵,從彈出菜單中找到複製連接地址單擊複製。github

支持systemd的linux系統(ubuntu,centos7)

我使用的是centos7的vps,經過ssh登錄進去,使用wget命令行工具把軟件包下載到 /opt目錄下。web

cd /opt
sudo wget 粘貼複製的連接
複製代碼

這時候將下載到的軟件包進行解壓。ubuntu

ls
sudo tar xzvf  軟件包名
複製代碼

解壓成功後進入剛剛解壓的文件目錄。vim

ls
cd 剛解壓的目錄
ls
複製代碼

能夠看到frpc,frps,frpc_full.ini,frps_full.ini,frpc.ini,frps.ini等文件,frps是服務端二進制程序,frpc是客戶端二進制程序,frps.ini是服務端的配置文件,frpc.ini是客戶端的配置文件,frps_full.ini跟frpc_full.ini是示例配置文件。 centos

在centos7下,能夠經過systemd來管理守護進程,根據此github項目上 issue上vc5寫的systemd 的service文件修改了一份frps程序可用的service文件,文件名改成frps.service,放在 /usr/lib/systemd/system/目錄下。

sudo cd /usr/lib/systemd/system
sudo vim frps.service
複製代碼

輸入上一行命令後,進入空的frps.service文件,點擊i進入編輯模式,複製粘貼下面的內容bash

[Unit]
Description=frps daemon
After=syslog.target  network.target
Wants=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.ini
Restart= always
RestartSec=1min
ExecStop=/usr/bin/killall frps

[Install]
WantedBy=multi-user.target
複製代碼

根據frps.service中啓動frps的那一行(ExecStart=......),將frps跟frps.ini移動或者複製到相應的目錄下。到這一步就能夠把下載的軟件包跟解壓出來的文件夾刪除了。服務器

cd /opt/frp文件夾名/
sudo cp frps /usr/local/bin#複製到該目錄下
sudo mkdir /etc/frp#新建文件夾frp
sudo cp frps.ini /etc/frp/#複製到該目錄下
sudo rm -rf 軟件包 解壓出來的文件夾
複製代碼

如今來設置/etc/frp目錄下的frps.ini,經過cd /etc/frp切換到該目錄下,輸入vim frps.ini 命令修改frps.ini,個人配置以下:

#frps.ini
[common]
bind_port = 1978#能夠自行設定

vhost_http_port = 8081#能夠自行設定
vhost_https_port = 4433#能夠自行設定

token=jsljgslaljglsgsgjlsjgslgjs#請本身設置密鑰
authentication_timeout=0#假如服務端與客戶端的時間相差超過24小時,可能會沒法鏈接,此處設置爲0,將再也不驗證服務端與客戶端時間

log_file = ./frps.log
log_level = info
log_max_days = 3

subdomain_host = example.com#填寫本身的域名,此處填寫subdomain_host則代理http,https協議時客戶端在web代理中要填寫subdomain項目

複製代碼

修改好frps.ini,服務端的配置基本完成,經過以下命令啓動運行:

sudo systemctl  enable frps.service#容許開機自啓
sudo systemctl  start frps.service#啓動
sudo systemctl  status frps.service#查看運行狀態

複製代碼

若是使用防火牆firewalld,frps相關服務端口可能並未開放,能夠經過以下命令開放相關端口:

sudo firewall-cmd --permanent --add-port=相關服務端口/tcp #此處端口是配置文件中設置好的端口,bind_port,vhost_http_port,vhost_https_port ,還有客戶端配置文件中的遠程端口,請逐條添加
sudo firewall-cmd --reload

複製代碼

客戶端配置

客戶端的配置前面幾步跟服務端相似,首先從此處找到適合本身系統架構的編譯好的軟件包並下載下來。

openwrt(LEDE)系統的路由器

把frpc複製到/usr/bin/目錄,把frpc.ini複製到/etc/目錄,根據網絡上的教程,我嘗試了在web管理界面中添加到本地啓動腳本中,輸入

nohup frpc -c /etc/frpc.ini > /dev/null 2>&1  &
複製代碼

但這樣開機啓動的方式並不起做用。因此我用python編寫了一個監測frpc是否運行的腳本,若是腳本檢測到frpc沒有運行就會啓動frpc。將該腳本命名爲monitor.py,放在/root目錄下,內容是這樣的:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import time

cmd="ps |grep frp |grep -v grep"
process=os.popen(cmd).readlines()
if process:
   time_now=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
   with open("monitor.log","at") as f:
        f.write(time_now+" running\n")
        for line in process:
            f.write(line)
else:
   time_now=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
   with open("monitor.log","at") as f:
        f.write(time_now+" no running\n")
   os.popen("frpc -c /etc/frpc.ini >/dev/null 2>&1 &")
複製代碼

將monitor.py賦予執行權限

chmod a+x monitor.py
複製代碼

咱們能夠在linux的計劃任務cron中每十分鐘運行一次腳本,咱們在/etc/crontabs/root文件的末尾添加上一條計劃任務

*/10 * * * * /root/monitor.py
複製代碼

客戶端配置文件frpc.ini:

[common]
server_addr = 0.0.0.0#填寫本身服務器ip
server_port=1978 #能夠自行設定
token=sgfsgsgshshshshshshshs #跟服務端必須一致

[ssh_router]#ssh鏈接
type = tcp
local_ip = 127.0.0.1
local_port = 22 #能夠自行設定
remote_port=4555#能夠自行設定

[web_router]#登陸web
type=http#或者https
local_ip=127.0.0.1
local_port =80#能夠自行設定
#此處無需設定遠程端口,服務端配置裏已經設置了vhost_http_port或vhost_https_port的端口
#若是服務端設置了subdomain_host,這裏設置subdomain,若是服務端沒有設置subdomain_host,這裏設置custom_domains
subdomain=router
#custom_domains = router.example.com

複製代碼

當客戶端配置文件修改好了,能夠輸入 frpc -c /etc/frpc.ini測試可否鏈接服務端,以下圖所示說明配置正確鏈接成功了。

frp客戶端成功鏈接服務端
如今重啓openwrt路由器,過幾分鐘監測腳本運行後就能夠從外網登錄路由器web界面了。前面的內容也適用於沒有使用systemd的其餘linux系統。

支持systemd的linux系統(ubuntu,centos7)

客戶端配置跟服務端幾乎同樣,只須要注意兩點,第一點就是編寫service文件時把 frps替換成frpc,第二點就是使用客戶端的配置文件frpc.ini。

歡迎瀏覽個人我的博客,https://diwugebingren.github.io

歡迎關注個人公衆號
相關文章
相關標籤/搜索