网络指南

basic

ip地址

参考:

IP地址

IP地址

ip地址(internet protocol address)全称是互联网协议地址,也称为网际协议地址

ip地址使用ip协议为主机和网络提供统一格式的逻辑地址,其目的是屏蔽物理地址的差异

目前最常用的ip地址包括ipv4地址和ipv6地址

ipv4地址

参考:

IPv4

ipv4(internet protocol version 4)表示ip协议的第4个版本,ip协议地址是目前最常用的地址格式

格式

ipv4地址长32位(4个字节),以点分十进制形式表示,即4个字节用点号隔开,以十进制表示

a.b.c.d
结构

ipv4地址结构经历过三个大的改变,一是设置两级IP地址,二是添加子网字段设置三级IP地址,三是无分类编址

_images/ip-address.PNG

设置两级IP地址

ipv4地址由两部分组成:

ipv4地址 = {<网络号>,<主机号>}

网络号标志主机(或路由器)所连接到的网络

主机号标志该主机(或路由器)

根据网络号的不同长度可分为A/B/C/D/E类网络

  • A类地址网络号长度为1个字节,前1位是类别位,规定为0
  • B类地址网络号长度为2个字节,前2位是类别位,规定为10
  • C类地址网络号长度为3个字节,前3位是类别位,规定为110
  • D类地址没有网络号,前4位是类别位,规定为1110
  • E类地址没有网络号,前4位为类别位,规定为1111

A/B/C类地址是单播地址,用于一对一通信

D类地址是多播地址,用于一对多通信

E类地址保留为以后使用

添加子网字段设置三级IP地址

参考:子网划分

ipv4地址由三部分组成:

ipv4地址 = {<网络号>,<子网号>,<主机号>}

网络号标志主机(或路由器)所连接到的网络

子网号标志主机(或路由器)所连接到的子网

主机号标志该主机(或路由器)

通过子网掩码区分子网号和主机号,子网掩码长32位,与ipv4地址一一对应,网络号和子网号的对应位置为1,主机号的对应位置为0

比如设置B类地址的子网号占3位,那么主机号占13位,子网掩码为

# 二进制
11111111 11111111 11100000 00000000
# 点分十进制
255.255.224.0

通过ipv4地址和子网掩码进行与运算,得到子网号和主机号

默认子网掩码

若网络不划分子网,就使用默认子网掩码

  • A类地址的默认子网掩码是255.0.0.0
  • B类地址的默认子网掩码是255.255.0.0
  • C类地址的默认子网掩码是255.255.255.0
子网个数

根据RFC 950文档,子网号不能为全1或全0(全0表示本网络,全1表示广播地址)

比如上例中B类地址的子网号占3位,子网掩码为255.255.224.0,其可划分子网数为2^3-2=6

主机号划分

主机号不能分配全1和全0地址

比如上例中B类地址的子网号占3位,那么主机号占13位,其可分配主机号个数为2^13-2=8190

无分类编址

无分类域间路由选择(Classles Inter-Domain Routing, CIDR)取消之前的A/B/C/D/E类地址和子网划分概念,将32ip地址划分为前后两个部分

ipv4地址 = {<网络前缀>,<主机号>}

其中网络前缀长度任意,通过斜线记法(slash notation),在ip地址后加上斜线,后面写上网络前缀的位数

xxx.xxx.xxx.xxx/22

在路由选择中使用32位的地址掩码,网络前缀的对应位数为1,主机号的对应位数为0

子网划分

各自单位在获取无分类编址后,仍旧可以划分子网,在原先的网络前缀中再加上子网位数

比如网络前缀长度为20,再继续划分8个子网(占3位),那么每个子网的网络前缀长度变成23

子网个数

根据RFC 1878文档,子网数可以为全1或者全0

ipv6地址

参考:IPv6

ipv6(internet protocol version 6)表示ip协议的第6个版本,其目的是提供更多的ip地址,解决ipv4地址资源有限的问题

ipv6地址长度为128位,采用16进制表示,使用冒分十六进制表示法

格式为X:X:X:X:X:X:X:X,每个X表示16位,用十六进制表示,比如ABCD:EF01:2345:6789:ABCD:EF01:2345:6789(每个X的前导0可以省略)

私有地址

参考:

内网服务

私有地址

RFC 1918指定了3个地址块仅能用于内部通信,不能在公网上和其他主机进行通信。RFC 6890全面给出了所有特殊用途的IPv4地址,针对这3个地址块没有变化

  1. 10.0.0.010.255.255.255(或记为10.0.0.0/8,又称为24位块,相当于一个A类网络)
  2. 172.16.0.0172.31.255.255(或记为172.16.0.0/12,又称为20位块,相当于16B类网络)
  3. 192.168.0.0192.168.255.255(或记为192.168.0.0/16,又称为16位块,相当于256C类网络)

路由器、交换机、集线器、中继器

网络和主机之间的传输依赖于硬件支持,常用的信号传输设备有集线器、中继器、路由器和交换机

_images/device-structure.PNG

路由器

参考:路由器

路由器(Router)又称为网关设备(Gateway),用于连接多个逻辑上分开的网络,是连接互联网中各局域网和广域网的设备

路由操作在网络层进行,路由器属于网络层的互联设备

交换机

参考:交换机

交换机(Switch)作用于数据链路层,通过MAC地址为接入交换机的任意两个节点提供独享的电信号通路,通常分为广域网交换机和局域网交换机

集线器

参考:集线器

集线器(Hub)主要功能是对接收到的信号进行再生放大,以扩大网络传输距离

集线器工作在局域网环境,属于物理层的互联设备

中继器

参考:

中继器

中继器

中继器(RP repeater)作用于物理层,其作用于两个同类网络的互联,主要功能是通过对数据信号的放大和转发,来扩大网络传输的距离

FAQ

参考:

如何跟小白解释路由器和交换机的区别?并且家用路由器充当了猫和路由器和交换机的功能吗?

集线器和交换机的区别?

1. 路由器和交换机的区别?

交换机根据MAC地址进行数据的传输和转发;而路由器根据IP地址进行数据的传输和转发

它们作用在网络体系结构中的不同层,交换机作用于数据链路层,路由器作用于网络层

2. 交换机和集线器的区别?

集线器仅对物理电信号进行放大,发送数据没有目标,对所有节点进行广播

交换机根据数据头的MAC地址进行转发,不会影响其他节点

集线器作用于物理层,交换机作用于数据链路层

3. 集线器和中继器的区别?

中继器仅有两个端口,仅起到连接作用

集线器有多个端口,除了再生放大信号其扩大网络距离外,还同时把所有节点集中在以它为中心的节点上,所有端口处于同一个冲突域,这样单条网络线路的故障不影响其他线路

局域网、广域网、互联网和私有专用网

参考:局域网,广域网,因特网之间的区别和联系?

局域网

参考:

局域网

局域网

局域网(Local Area NetWork, LAN)指在某一区域内由多台计算机互联组成的计算机网络

局域网内的主机通过同一个路由器对外传输和转发数据,通过若干个集线器或交换机进行内部交流

局域网通常覆盖的地理范围小,建设、维护和扩展灵活,同时网络延时低,数据传输率高,可靠性高

广域网

参考:广域网

广域网(Wide Area Network, WAN)指的是连接多个局域网或城域网通信的计算机网络

互联网

参考:互联网

互联网(Internet)指的是通过一组通用协议来串联不同广域网从而得到的计算机网络

虚拟专用网

参考:

VPN

虚拟专用网

虚拟专用网(Visual Private Network, VPN)在公网上建立专用网络,进行加密通讯

它模拟了单个局域网内的通信,但实际是通过公网进行不同局域网之间的远程通信

相互关系

_images/network-scope.PNG

网络体系结构

参考:OSI七层模型和两主机传输过程(转)

计算机网络的各层及其协议的集合就是计算机网络体系结构

其设计目的是通过对网络的分层,将各个系统硬软件的差异转化成较小的局部问题,更易于研究和处理,最终保证遵循同一套体系结构的系统能够相互通信

目前并行有两套网络体系结构:

  1. 开放系统互联基本参考模型OSI/RM
  2. TCP/IP体系结构

开放系统互联基本参考模型OSI/RM

开发系统互联基本参考模型(Open Systems Interconnection Reference Model, OSI/RM)是国际标准化组织ISO制定的,在1983年形成正式的文件,即ISO 7498国际标准,简称为OSI

OSI是一个7层协议的体系结构,从上到下分别是应用层、会话层、表示层、运输层、网络层、数据链路层、物理层

_images/OSI.PNG

OSI并没有获得大规模的应用,因为同一时期出现的TCP/IP四层网络系统结构已经抢先在全世界大范围的运行

TCP/IP体系结构

TCP/IP体系结构共4层,分别由应用层、运输层、网际层和网络接口层构成

_images/tcp-ip.PNG

其与OSI体系结构对应如下

_images/osi-tcp-ip.PNG

层解析

  1. 应用层(application layer):其任务是通过应用进程间的交互来完成特定网络应用
  2. 运输层(transport layer):其任务是负责向两台主机之间的通信提供通用的数据传输服务。应用进程通过该服务来传送应用层报文
  3. 网络层(network layer):负责为分组交换网上的不同主机提供通信服务。在发送数据时,将运输层生成的报文段用户数据报封装成分组进行传送
  4. 数据链路层(data link layer):负责两台主机之间的数据在链路上的传输。将网络层得到的数据包封装成
  5. 物理层(physical layer):确定电压大小(多大是1、多大是0)以及接收方如何识别发送方所发送的比特等关于硬件的参数

URL构成

参考:

快速搞懂URL的构成

URL的各个组成部分详解

URL

简介

URL(Uniform Resource Locator)用于表示互联网上资源(文件)的具体位置

语法

URL的实现符合通用的URI(Uniform Resource Identifier)语法,由五个组件的层次结构序列组成

URI = scheme:[//authority]path[?query][#fragment]

其中authority部分还可分为3个组件

authority = [userinfo@]host[:port]

所以完整的语法如下:

scheme:[//[userinfo@]host[:port]]path[?query][#fragment]

_images/URI_syntax_diagram.svg.png

语法解析

  • scheme组件表示传输协议,常用的有http/https/ftp/mailto/file等等
  • authority组件用于指定服务器位置,指定主机名和端口号,还可能包含用户名和密码
    • 如果包含用户名和密码:[//[username[:passwd]]host[:port]]
    • 通常仅指定主机名和端口号:[//host[:port]]
    • 主机名可以用IP地址或者域名表示;如果忽略端口号,表示使用80端口
  • path组件指定资源在服务器中的位置
  • query组件表示查询参数,包含一组查询字符串
    • 其语法没有很好定义,通常是由一个分隔符分隔的一系列属性-值对
    • key1=value1&key2=value2
  • fragment组件表示锚部分,指定文件打开时页面滚动到锚点位置

示例

https://www.zhujian.tech
  • 指定传输协议为https
  • 主机名为www.zhujian.tech
  • 使用默认端口80
https://github.com/zjZSTU/network-guide
  • 指定传输协议为https
  • 主机名为github.com
  • 使用默认端口80
  • 资源路径为/zjZSTU/network-guide
http://localhost:8080/jenkins
  • 指定传输协议为http
  • 主机名为localhost
  • 指定端口8080
  • 资源路径为/jenkins
https://fanyi.baidu.com/?aldtype=16047#zh/en/
  • 指定传输协议为https
  • 主机名为fanyi.baidu.com
  • 使用默认端口80
  • 资源路径为/
  • 查询参数为aldtype=16047
  • 锚点位置为zh/en/

DNS解析过程

参考:

面试官:讲讲DNS的原理?

DNS原理及解析过程详解

DNS解析全过程分析

DNS解析过程就是将域名转换成IP地址的过程

DNS简介

DNS(Domain Name System,称为域名系统),是一种组织成域层次结构的计算机和网络服务命名系统,它作用于TCP/IP网络,所提供的服务是用来将主机名和域名转换为IP地址的工作

解析过程

浏览器从URL中解析出host字段后,依次按如下顺序进行查询:

  1. 从浏览器缓存中查找是否有该域名对应的IP地址。如果没有访问过该域名或者缓存已清空,则使用第二步
  2. 查询系统缓存,从hosts文件中查找是否存在该域名以及对应IP。如果不存在,使用第三步
  3. 查询路由器缓存

以上3步均在DNS客户端完成,后续操作将请求域名服务器

/etc/hosts

参考:linux环境下/etc/hosts文件详解

hosts文件是linux系统中负责ip地址与域名快速解析的文件,DNS客户端首先查询缓存,然后查询hosts文件,最后查询DNS服务器

Ubuntu中的文件地址为/etc/hosts

$ cat /etc/hosts
127.0.0.1	localhost
127.0.1.1	zj-ThinkPad-T470p

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

0.0.0.0 account.jetbrains.com

每行表示一条域名解析,其格式为

ip地址 主机名/域名 [主机别名]

nginx

[Ubuntu 16.04]nginx安装

参考:Installing nginx

当前在Ubuntu 16.04下安装Nginx

安装预置应用

sudo apt install curl gnupg2 ca-certificates lsb-release

安装稳定版nginx

echo "deb http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

导入官方nginx签名密钥

curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

验证

sudo apt-key fingerprint ABF5BD827BD9BF62

结果如下

pub   2048R/7BD9BF62 2011-08-19 [expires: 2024-06-14]
    Key fingerprint = 573B FD6B 3D8F BC64 1079  A6AB ABF5 BD82 7BD9 BF62
uid                  nginx signing key <signing-key@nginx.com>

安装nginx

sudo apt update
sudo apt install nginx

[Ubuntu 16.04]nginx测试

参考:

linux下解决80端口被占用

Nginx安装

nginx占用80端口,确保未被使用

$ sudo netstat -lnp | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      22308/nginx: master

如果已被占用则退出该进程

$ sudo kill 22308

启动nginx

$ sudo nginx
$ ps -ef | grep nginx
root      1068     1  0 16:31 ?        00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
nginx     1069  1068  0 16:31 ?        00:00:00 nginx: worker process
ubuntu   15252  1320  0 19:13 pts/0    00:00:00 grep --color=auto nginx

打开浏览器,访问该机器的ip,即会出现nginx欢迎页面

_images/welcome-nginx.png

[Ubuntu 16.04]nginx配置

nginx相关

参考:1.阿里云 ubuntu 服务器安装nginx爬坑小结

nginx可执行文件

$ file /usr/sbin/nginx 
/usr/sbin/nginx: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=aea1a3059091725ead573b5845a31286fd6170c1, stripped

nginx配置文件/etc/nginx/nginx.conf

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

nginx版本信息

$ nginx -v
nginx version: nginx/1.10.3 (Ubuntu)

nginx配置参数

$ nginx -V
nginx version: nginx/1.10.3 (Ubuntu)
built with OpenSSL 1.0.2g  1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads

配置文件

默认配置为/etc/nginx/nginx.conf

$ cat nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

http设置包括了/etc/nginx/conf.d下的*.conf文件,里面有一个默认配置default.conf

$ cat conf.d/default.conf
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

默认监听端口为80, 服务器名为当前ip,根目录为/usr/share/nginx/html

[Ubuntu 16.04]nginx中文乱码

参考:

Nginx 显示中文乱码解决

修改配置文件/etc/nginx/conf.d/default.conf,添加

charset utf-8;

$ cat default.conf 
server {
    ...
    ...
    charset utf-8;
    #charset koi8-r;
    ...
}

重启nginx服务

sudo service nginx restart

在浏览器刷新页面(Ctrl+F5)即可

[Ubuntu 16.04]nginx托管静态网站

参考:

Ubuntu服务器使用Nginx配个静态网站

nginx启动后,打开浏览器输入服务器ip,显示一个欢迎页面,其地址为

/usr/share/nginx/html/index.html

其在配置文件/etc/nginx/conf.d/default.conf中引用

$ cat conf.d/default.conf
server {
        listen       80;
        server_name  localhost;
        ...
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
        ...
    }

托管静态文件

参考:W3School TIY

新建文件夹blogs

$ mkdir blogs
$ cd blogs/
$ pwd
/home/ubuntu/blogs

在里面新建文件index.html

$ vim index.html
<html>

<head>
<title>我的第一个 HTML 页面</title>
</head>

<body>
<p>body 元素的内容会显示在浏览器中。</p>
<p>title 元素的内容会显示在浏览器的标题栏中。</p>
</body>

</html>

修改default.conf文件,修改root路径为blogs

$ sudo vim default.conf
server {
    ...
    location / {
        root   /home/ubuntu/blogs;
        index  index.html index.htm;
    }
}

重启nginx

sudo source nginx restart

在浏览器输入服务器ip

_images/first-index.png

绑定域名

参考:Server names

修改default.conf下的server_name选项,设置成自定义域名

server {
    listen       80;
    server_name  example.org  www.example.org;
    ...
}

然后到域名解析中添加服务器ip

注意:需要云服务器开启80端口,腾讯云服务器需要进行安全组配置

绑定404页面

修改default.conf,取消404页面的注释,使用root路径下的404.html(也可以设置成其他路径)

#error_page  404              /404.html;

[Ubuntu 16.04]nginx配置HTTPS

参考:

Nginx/Tengine服务器安装SSL证书

2. Nginx 证书部署

共分4步进行:

  1. 申请CA服务
  2. 配置CA证书
  3. 配置nginx
  4. 重启nginx

申请CA服务

首先在阿里云腾讯云上申请CA证书服务

_images/aliyun-ca.png

有免费CA证书可以申请,参考:SSL证书申请

配置CA证书

购买完成后进入控制台,下载相应的实例(选择nginx版本下载)

_images/purchased-ca.png

是一个zip压缩包,里面有两个文件:一个.key文件(加密)和一个.pem文件(证书)

nginx配置路径下新建文件夹cert,解压放置其中

/etc/nginx/cert/

配置nginx

修改/etc/nginx/conf.d/default.conf文件如下:

$ cat default.conf 
server {
    listen 80; # http端口
    server_name 自己的域名;
    return 301 https://$host$request_uri; # 跳转到https
}
server {
    listen       443; # https端口
    server_name  自己的域名;

    charset utf-8;
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    ssl on;
    ssl_certificate cert/1771479_www.zhujian.tech.pem;
    ssl_certificate_key cert/1771479_www.zhujian.tech.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; # 阿里云和腾讯云会有差别
    ssl_prefer_server_ciphers on;

    location / {
        root   /home/ubuntu/blogs; # 静态文件根路径
        index  index.html index.htm;
    }

    error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

重启nginx

先测试配置文件是否正确

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

再重启nginx

$ sudo service nginx restart

[Ubuntu 16.04]nginx反向代理

反向代理简介

参考:Nginx Reverse Proxy

反向代理(reverse proxy)用于代理服务器,用户输入代理服务器地址,通过nginx请求正确的服务器地址,并将资源返回给用户

https://upload-images.jianshu.io/upload_images/5107794-9c9764e76dfa7b2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1030/format/webp

配置

参考:

Module ngx_http_proxy_module

NGINX Reverse Proxy

nginx location 语法

使用指令proxy_pass指定反向代理的服务器地址,在/etc/nginx/conf.d/目录下添加配置文件test.conf

{
    listen 80;
    server_name localhost;

    location /jk/ {
        proxy_pass http://localhost:8080/jenkins/;
    }
}

URL符合localhost/jenkins/时,nginx将会请求代理地址

注意:上面的代理服务器地址指定了资源地址为/jenkins/,则该字段将替代location匹配的参数/jk。比如客户端请求地址为http://localhost/jk/page.htmlnginx代理后的地址为http://localhost:8080/jenkins/page.html

所以上面代码也可以修改如下:

...
    location /jenkins/ {
        proxy_pass http://localhost:8080;
    }
...

反向代理过程

参考:nginx做反向代理处理http请求的过程

nginx安装在本地,所以当URL输入localhost/jenkins/

  1. 解析域名为IP地址127.0.0.1,请求本地nginx进行处理
  2. nginxURL转换成http://localhost:8080/jenkins/后再次请求
  3. nginx获得html数据后转发给浏览器

下面实现输入www.123.com/jenkins/,反向代理到http://localhost/jenkins/

修改/etc/hosts文件,将域名www.123.com映射到nginx服务器地址127.0.0.1

127.0.0.1   www.123.com

添加nginx配置文件/etc/nginx/conf.d/test.conf

server {
    listen       80;
    server_name  www.123.com;

    location /jenkins/ {
        proxy_pass  http://localhost:8080/jenkins/;
    }
}

热更新nginx

$ sudo nginx -s reload

在浏览器登录www.123.com/jenkins/,即可登录本地安装的jenkins

_images/nginx-jenkins.png

如果不成功,可能是由于DNS缓存的关系,需要清空浏览器缓存和系统缓存

[Ubuntu 16.04]docker安装nginx

主要参考Docker 安装 Nginx完成nginx的安装和配置

镜像下载

Docker提供了官方nginx

$ docker pull nginx

启动

使用如下命令:

$ docker run --name nginx-test -p 7700:80 -d nginx
  • --name:容器名
  • -p:映射主机7700端口到容器80端口
  • -d:后台运行

打开浏览器,登录localhost:7700查看是否成功

_images/welcome_nginx.png

配置

在主机创建文件夹

$ mkdir -p ~/nginx/www ~/nginx/logs ~/nginx/conf.d
  • www:保存html文件
  • logs:保存nginx运行日志
  • conf.d:保存配置文件

将容器内Nginx配置文件拷贝到主机

$ docker cp CONTAINER_ID:/etc/nginx/nginx.conf ~/nginx
$ docker cp COMTAINER_ID:/etc/nginx/conf.d/default.conf ~/nginx/conf.d

:~/nginx$ tree
.
├── conf.d
│   └── default.conf
├── logs
│   ├── access.log
│   └── error.log
├── nginx.conf
└── www
    └── index.html

修改配置文件~/nginx/conf.d/default.conf,修改Location

...
...
    location / {
        #root   /usr/share/nginx/html;
        root   /opt/www;
        index  index.html index.htm;
    }
...
...

~/nginx/www目录下创建文件index.html

<!DOCTYPE html>
<html>
<head>
<title>Docker Nginx</title>
</head>

<body>
Hello Nginx
</body>

</html>

重新启动nginx注意端口冲突,可以调整主机端口或停止之前的容器),命令如下:

$ docker run -d -p 7700:80 \
    --name nginx-test-web \
    -v ~/nginx/www:/opt/www \
    -v ~/nginx/logs:/var/log/nginx \
    -v ~/nginx/conf.d:/etc/nginx/conf.d \
    -v ~/nginx/nginx.conf:/etc/nginx/nginx.conf \
    nginx
  • -d:后台运行
  • -p:映射主机7700端口到容器80端口
  • --name:设置容器名
  • -v:挂载本地目录到容器中

_images/hello-nginx.png

上述操作后nginx将使用主机保存的配置文件,可以修改~/nginx/conf.d/default.conf,重新启动正在运行的容器即可更新配置

$ docker restart COMTAINER_ID

tomcat

关于Tomcat

Tomcat文档在开头提供了一些重要的信息和内容 - Introduction

术语

具体规范参考:Servlet and JSP specifications。比如

  • Context - 表示一个Web应用程序

目录和文件

重要的tomcat目录:

  1. /bin:启动、关闭以及其他一些脚本
  2. /conf:配置文件和相关的DTDs,其中最重要的配置文件就是server.xml
  3. /logs:默认放置的日志目录
  4. /webappswebapp存放的目录

CATALINA_HOME和CATALINA_BASE

需要设置两个重要的环境变量:

  1. CATALINA_HOME:表示Tomcat安装路径
  2. CATALINA_BASE:表示特定Tomcat实例的运行时配置的根路径

默认情况下,两个环境变量设置为相同路径

[Ubuntu 16.02]Tomcat9安装

参考:

Ubuntu16.04安装Tomcat

Ubuntu16.04服务器安装tomcat

先决条件

Tomcat需要预先安装JDK

下载

当前最新版本:Tomcat 9.0.27。下载地址:Tomcat 9 Software Downloads

配置

解压到/opt/tomcat目录下,在bin目录下新建文件setenv.sh如果没有的话

# JAVA
export JAVA_HOME=/home/zj/software/java/jdk1.8.0_201
export JRE_HOME=$JAVA_HOME/jre

# Tomcat
export CATALINA_HOME=/opt/tomcat/apache-tomcat-9.0.27
export CATALINA_BASE=/opt/tomcat/apache-tomcat-9.0.27

启动

执行文件/bin/startup.sh,即可启动Tomcat

$ ./startup.sh 
Using CATALINA_BASE:   /opt/tomcat/apache-tomcat-9.0.27
Using CATALINA_HOME:   /opt/tomcat/apache-tomcat-9.0.27
Using CATALINA_TMPDIR: /opt/tomcat/apache-tomcat-9.0.27/temp
Using JRE_HOME:        /home/zj/software/java/jdk1.8.0_201/jre
Using CLASSPATH:       /opt/tomcat/apache-tomcat-9.0.27/bin/bootstrap.jar:/opt/tomcat/apache-tomcat-9.0.27/bin/tomcat-juli.jar
Tomcat started.

查询localhost:8080是否已被监听

# curl localhost:8080
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/9.0.27</title>
...
...

_images/tomcat-8080.png

停止

调用脚本/bin/shutdown.sh

开机自启动

修改文件/etc/rc.local

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

/opt/tomcat/apache-tomcat-9.0.27/bin/startup.sh

exit 0

非root用户运行

参考:

用非root用户启动tomcat进程

How To Install Apache Tomcat 8 on Ubuntu 16.04

Tomcat用普通用户身份运行

默认安装的tomcatroot用户运行,为保证其安全性,进一步设置tomcat以普通用户运行

创建tomcat用户

创建新用户tomcat,设置home目录为/opt/tomcat

$ useradd -d /opt/tomcat tomcat

修改/opt/tomcat文件属主为tomcat

$ sudo chown -R tomcat:tomcat apache-tomcat-9.0.27

实现

切换到tomcat用户后进行启动即可;如果是开机自启动,则修改/etc/rc.local

su tomcat -c "/opt/apache-tomcat-9.0.27/bin/startup.sh"

这篇文章How To Install Apache Tomcat 8 on Ubuntu 16.04也介绍的很详细

其他实现

tomcat提供了工具jsvc,允许tomcat以非root用户运行,参考Unixroot daemon

内网穿透

前言

参考:

内网穿透

nat穿透

在学校实验室使用Jenkins,想要实现github连接,所以需要进行内网穿透,将局域网端口映射到公网

常用的内网穿透方法包括

  1. 路由器的虚拟服务器设置
  2. 花生壳的内网穿透服务
  3. n2np2p节点连接
  4. ssh端口转发:实战 SSH 端口转发

[内网穿透][路由器]虚拟服务器

参考:路由器虚拟服务器(端口映射)设置指导

最方面的操作就是通过路由器的虚拟服务器功能进行端口映射

设置

进入设置页面,选择高级功能->虚拟服务器,点击新增按钮

_images/router-visual-setting.png

输入规则名称(自定义)、生效接口(就是WAN口,默认仅有一个WAN1口)、外部端口、内部端口、内部服务器IP

实验室使用

因为实验室局域网位于学校大局域网下,所以通过路由器的虚拟服务器功能映射出去的端口仍旧处于内网中,github无法访问

[内网穿透]花生壳

参考:

如何进入学校内网?花生壳“内网穿透”服务帮上大忙

用花生壳实现访问局域网内的SVN

花生壳是一款动态域名解析软件,通过它能够实现端口映射功能

安装

参考:花生壳 3.0 for Linux 相关安装使用文档

下载安装包,以root用户进行安装

# 切换为root
$ sudo su
# 安装
$ dpkg -i phddns_3.0_x86_64.deb

安装完成后会生成SN用户名和密码

_images/oray-login.png

phddns使用

# 当前版本
$ phddns version
# 当前状态
$ phddns status

# 启动
$ phddns start
# 重启
$ phddns restart
# 停止
$ phddns stop
# 重置
$ phddns reset

官网设置

登录网站,使用之前的生成的SN用户名和密码登录,默认会赠送一个域名

如果已注册过网站,先使用SN用户名和密码登录,然后选择切换帐号服务,将SN绑定到之前的帐号

_images/switch-account.png

先购买体验版套餐,就可以设置端口映射

_images/port-setting.png

添加映射不成功

问题:填写完内网ip/端口后,点击确定按钮提示不成功

解决:1. 确保客户端已启动;2. 使用SN用户名和密码登录

[内网穿透]n2n原理

n2n是一个开源的2P2P架构VPN,有如下特点:

  1. 基于P2P协议的加密2层专用网络
  2. 边缘节点(edge node)的加密是使用带有用户自定义密码的开放协议
  3. 每个n2n用户可以同时加入不同的网络(或称为社区)
  4. n2n能够以反向流量方向(即从外部到内部)跨越NAT和防火墙。防火墙不再是IP级别直接通信的障碍。
  5. n2n网络并不意味着是独立的:可以通过n2n和非n2n网络连接。

网络结构

n2n是一个2层网络架构,分别由核心节点(supernode)和边缘节点(edgenode)构成

_images/n2n_network.png

边缘节点运行在客户端,通过创建虚拟网卡作为n2n网络的入口

核心节点作为服务器端,作为边缘节点的目录寄存器(directory register)和包路由器(packet router)

n2n优势

n2n网络通过虚拟网卡,利用UDP协议进行通信,每个边缘节点(客户端)可以创建多个虚拟网卡,可以从属于多个不同网络

_images/n2n_com.png

边缘节点通过核心节点握手后可以直接通信,这样能够降低通信的延时,也能够减轻核心节点的带宽压力

_images/n2n_nat.png

[内网穿透]n2n实现

参考:

n2n内网穿透打洞部署全过程 + nginx公网端口映射

如何在 Linux 上配置点对点 VPN

安装

下载ntop/n2n源码

git clone https://github.com/ntop/n2n.git

安装其他库

$ sudo apt-get install cmake make libssl-dev

切换到v2版本

$ git checkout -b 2.4-stable origin/2.4-stable
Branch 2.4-stable set up to track remote branch 2.4-stable from origin.
Switched to a new branch '2.4-stable'

链接、编译和安装

$ cmake .
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenSSL: /usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so (found version "1.0.2g") 
CMake Warning (dev) at CMakeLists.txt:79 (add_executable):
  Policy CMP0037 is not set: Target names should not be reserved and should
  match a validity pattern.  Run "cmake --help-policy CMP0037" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  The target name "test" is reserved or not valid for certain CMake features,
  such as generator expressions, and may result in undefined behavior.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/n2n

$ make
Scanning dependencies of target doc
[ 11%] Built target doc
Scanning dependencies of target n2n
[ 15%] Building C object CMakeFiles/n2n.dir/n2n.c.o
[ 19%] Building C object CMakeFiles/n2n.dir/n2n_keyfile.c.o
[ 23%] Building C object CMakeFiles/n2n.dir/edge_utils.c.o
[ 26%] Building C object CMakeFiles/n2n.dir/wire.c.o
[ 30%] Building C object CMakeFiles/n2n.dir/minilzo.c.o
[ 34%] Building C object CMakeFiles/n2n.dir/twofish.c.o
[ 38%] Building C object CMakeFiles/n2n.dir/transform_null.c.o
[ 42%] Building C object CMakeFiles/n2n.dir/transform_tf.c.o
[ 46%] Building C object CMakeFiles/n2n.dir/transform_aes.c.o
[ 50%] Building C object CMakeFiles/n2n.dir/tuntap_freebsd.c.o
[ 53%] Building C object CMakeFiles/n2n.dir/tuntap_netbsd.c.o
[ 57%] Building C object CMakeFiles/n2n.dir/tuntap_linux.c.o
[ 61%] Building C object CMakeFiles/n2n.dir/tuntap_osx.c.o
[ 65%] Building C object CMakeFiles/n2n.dir/version.c.o
[ 69%] Linking C static library libn2n.a
[ 69%] Built target n2n
Scanning dependencies of target supernode
[ 73%] Building C object CMakeFiles/supernode.dir/sn.c.o
[ 76%] Linking C executable supernode
[ 76%] Built target supernode
Scanning dependencies of target edge
[ 80%] Building C object CMakeFiles/edge.dir/edge.c.o
[ 84%] Linking C executable edge
[ 84%] Built target edge
Scanning dependencies of target benchmark
[ 88%] Building C object CMakeFiles/benchmark.dir/benchmark.c.o
[ 92%] Linking C executable benchmark
[ 92%] Built target benchmark
Scanning dependencies of target test
[ 96%] Building C object CMakeFiles/test.dir/test.c.o
[100%] Linking C executable test
[100%] Built target test
ubuntu@VM-16-15-ubuntu:~/n2n$ make install
[ 11%] Built target doc
[ 69%] Built target n2n
[ 76%] Built target supernode
[ 84%] Built target edge
[ 92%] Built target benchmark
[100%] Built target test

$ sudo make install
[ 11%] Built target doc
[ 69%] Built target n2n
[ 76%] Built target supernode
[ 84%] Built target edge
[ 92%] Built target benchmark
[100%] Built target test
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/sbin/edge
-- Installing: /usr/local/sbin/supernode
-- Installing: /usr/share/man8/edge.8.gz
-- Installing: /usr/share/man1/supernode.1.gz
-- Installing: /usr/share/man7/n2n.7.gz

配置

参考:

当前有3台电脑

  1. 实验室服务器A
  2. 腾讯云服务器B
  3. 自己笔记本C

B作为服务器端,启动supernode

$ supernode -l 3307 -v
  • -l表示UDP监听端口
  • -v表示详细输出

AC作为客户端,启动edge

# A操作
$ sudo edge -d n2n0 -c mynetwork -k encryptme -a 172.16.0.200 -l a.b.c.d:3307 -M 1200 -m ae:e0:4f:e7:47:5c
# C操作
$ sudo edge -d n2n0 -c mynetwork -k encryptme -a 172.16.0.201 -l a.b.c.d:3307 -M 1200 -m ae:e0:4f:e7:47:5b
  • -d表示新建虚拟网卡名
  • -c表示n2n社区名
  • -k表示加密键值
  • -a表示自定义ip
  • -l表示服务器ip:监听端口
  • -M表示虚拟网卡最大传输单位
  • -m表示虚拟网卡MAC地址
调试边缘节点

添加参数-v-f

  • -f表示在前台运行edge而不是作为守护进程
  • -v表示详细输出
终止边缘节点

查询pid并终止

$ ps aux | grep edge
root     28348  0.0  0.0  10888   316 ?        Ss   15:50   0:00 edge -d n2n0 -c xxx
zj       29947  0.0  0.0  15964  1016 pts/23   S+   16:09   0:00 grep --color=auto edge
$ sudo kill -9 28348
稳定性

隔一段时间ping内网服务器会发现无法连接

PING 172.16.0.200 (172.16.0.200) 56(84) bytes of data.
From 172.16.0.201 icmp_seq=1 Destination Host Unreachable

参考搜集整理N2N使用中的一些经验,是因为edge休眠了,持续一段时间就能够ping通了

$ ping 172.16.0.200
PING 172.16.0.200 (172.16.0.200) 56(84) bytes of data.
From 172.16.0.201 icmp_seq=1 Destination Host Unreachable
From 172.16.0.201 icmp_seq=2 Destination Host Unreachable
From 172.16.0.201 icmp_seq=3 Destination Host Unreachable
From 172.16.0.201 icmp_seq=4 Destination Host Unreachable
From 172.16.0.201 icmp_seq=5 Destination Host Unreachable
From 172.16.0.201 icmp_seq=6 Destination Host Unreachable
From 172.16.0.201 icmp_seq=7 Destination Host Unreachable
From 172.16.0.201 icmp_seq=8 Destination Host Unreachable
From 172.16.0.201 icmp_seq=9 Destination Host Unreachable
From 172.16.0.201 icmp_seq=10 Destination Host Unreachable
From 172.16.0.201 icmp_seq=11 Destination Host Unreachable
From 172.16.0.201 icmp_seq=12 Destination Host Unreachable
From 172.16.0.201 icmp_seq=13 Destination Host Unreachable
64 bytes from 172.16.0.200: icmp_seq=14 ttl=64 time=1200 ms
64 bytes from 172.16.0.200: icmp_seq=15 ttl=64 time=176 ms
64 bytes from 172.16.0.200: icmp_seq=16 ttl=64 time=87.6 ms
64 bytes from 172.16.0.200: icmp_seq=17 ttl=64 time=99.2 ms
64 bytes from 172.16.0.200: icmp_seq=18 ttl=64 time=87.2 ms
64 bytes from 172.16.0.200: icmp_seq=19 ttl=64 time=88.7 ms
64 bytes from 172.16.0.200: icmp_seq=20 ttl=64 time=88.6 ms
^C
--- 172.16.0.200 ping statistics ---
20 packets transmitted, 7 received, +13 errors, 65% packet loss, time 19311ms
rtt min/avg/max/mdev = 87.257/261.182/1200.246/384.543 ms, pipe 4

[内网穿透]ngrok实现

ngrok是一种反向代理服务,能够实现内网穿透。首先介绍其官网实现,再自建ngrok服务器

官网实现

ngrok官网已经搭建好了服务器,同时提供了客户端以及详细的教程

注册好后登录到个人主页,下载客户端进行配置

  1. 下载客户端
  2. 解压压缩包
  3. 运行客户端程序添加账户的authtoken到配置文件ngrok.yml
  4. 启动客户端

配置文件ngrok.yml默认放置在~/.ngrok2目录下

ngrok可使用不同协议进行通信,当前实现ssh连接,执行如下命令:

$ ./ngrok tcp 22

_images/ngrok_online.png

配置成功后在官网个人主页的状态栏中会列出连接的信息

_images/tunnels_online.png

这样就可以在本地打开命令行窗口连接到内网

$ ssh -p 12544 内网服务器用户名@0.tcp.ngrok.io
The authenticity of host '[0.tcp.ngrok.io]:12544 ([3.17.202.129]:12544)' can't be established.
ECDSA key fingerprint is SHA256:YXdgs3OJN0yxuNLLU.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[0.tcp.ngrok.io]:12544,[3.17.202.129]:12544' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-130-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

544 packages can be updated.
393 updates are security updates.

Last login: Thu Jul 11 11:00:36 2019 from 127.0.0.1
$ 

自建ngrok服务器

参考:

How to run your own ngrokd server

Developer’s guide to ngrok

ngrok实现公网访问内网主机并开机启动,远程管理,校外也能看论文

搭建并配置优雅的 ngrok 服务实现内网穿透

使用官网服务器进行内网穿透很方便,不过其延迟比较大,估计是因为服务器都搭建在国外,作者inconshreveable开源了其ngrok实现,所以可以自建服务器进行配置

_images/ngrok.png

共分为6

  1. SSL证书配置
  2. DNS修改
  3. 客户端和服务器软件编译
  4. 服务器软件运行
  5. 客户端配置
  6. 客户端运行
SSL证书配置

ngrok通过SSL证书进行安全通信,有两种方式创建SSL证书,一是购买公共SSL证书,另一种是自建SSL证书,我在阿里云上购买了免费的SSL证书

证书申请成功后下载解压后得到两个文件:***.key***.pem

如果不是使用https隧道(比如http隧道、ssh隧道等),在证书上绑定指定域名即可,比如ngrok.xxx.com;否则添加一个通配符(wildcard)域名,比如*.xxx.com

DNS修改

自建服务器需要申请一个域名,同时在DNS解析设置上新增一条A记录,将指定域名和服务器IP进行绑定

客户端和服务器软件编译
环境配置

当前使用腾讯云服务器,首先配置运行环境(编译器+go环境)

$ sudo apt-get install mercurial git gcc g++

安装go,参考Getting Started

# 下载已编译压缩包
$ wget https://dl.google.com/go/go1.12.1.linux-amd64.tar.gz
# 解压到指定路径
$ sudo tar -C /usr/local -xzf go1.12.1.linux-amd64.tar.gz
# 设置全局变量
$ export PATH=$PATH:/usr/local/go/bin
# 测试
$ go version
go version go1.12.1 linux/amd64

设置环境变量GOOS/GOARCH为指定服务器和客户端平台,比如

$ export GOOS=linux
$ export GOARCH=amd64
ngrok编译

下载ngrok源码

$ git clone https://github.com/inconshreveable/ngrok.git

编译服务器和客户端软件

# 两个平台都一样的话同时编译
$ make release-all
# 或者分开编译,注意GOOS/GOARCH设置
$ make release-server
$ make release-client

生成的文件在bin目录下,ngrok是客户端应用,ngrokd是服务器应用

服务器软件运行

运行如下命令:

$ ./ngrokd -tlsKey=a.key -tlsCrt=a.pem -domain="ngrok.example.com" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062"
  • tlsKeytlsCrt表示SSL证书地址
  • domain表示之前配置的域名
  • ngrok服务器会监听HTTPS/HTTPSs/TCP端口,默认是80/443/4443,修改为其他端口号

注意:腾讯云服务器上需要在安全组设置中开放上述端口号

客户端配置

下载编译好的ngrok到内网电脑上,创建配置文件ngrok.cfg:

$ cat ngrok.cfg 
server_addr: ngrok.xxx.xxx:6062
trust_host_root_certs: true
tunnels:
  ssh:
    remote_port: 12345
    proto:
      tcp: 22

配置文件指定了远程服务器地址和端口号,并指定了远程映射的端口号12345以及使用的协议和本地端口号22,表明将远程端口号12345和本地端口号22进行绑定

参数trust_host_root_certs用于SSL证书配置,如果使用了公共证书,设置为true;如果使用了私有证书,设置为false

注意:同样需要在安全组中开放端口12345

客户端运行

运行如下命令:

$ ./ngrok -config ngrok.cfg -log ngrok.log start ssh

参数config指定配置文件,参数log指定日志文件

_images/ngrok_online2.png

运行成功后就可以打开命令行窗口登录

$ ssh -p 12345 zj@ngrok.xxx.xxx  # zj是内网的用户名
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-130-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

544 packages can be updated.
393 updates are security updates.

Last login: Thu Jul 11 12:25:19 2019 from 127.0.0.1
$ 

系统服务设置

外网服务器系统服务配置

在云服务器上新建ngrokd.service,目录是/etc/systemd/system/

$ cat ngrokd.service 
[Unit]
Description=ngrok

[Service]
ExecStart=/bin/bash /opt/ngrokd/ngrokd.sh

[Install]
WantedBy=multi-user.target

赋予可执行权限777

$ sudo chmod 777 ngrokd.service

其作用是执行/opt/ngrokd/ngrokd.sh脚本,脚本实现如下:

$ cat ngrokd.sh 
#!/bin/bash

cd /opt/ngrokd

./ngrokd -tlsKey=a.key -tlsCrt=a.pem -domain="ngrok.zhujian.com" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062"

同样授予脚本可执行权限

内网服务器系统服务配置

同样在内网电脑上编写脚本ngrok.sh

#!/bin/bash

cd /opt/ngrok

./ngrok -config ngrok.cfg -log ngrok.log start ssh

/etc/systemc/system目录下编写服务ngrok.service

[Unit]
Description=ngrok

[Service]
ExecStart=/bin/bash /opt/ngrok/ngrok.sh

[Install]
WantedBy=multi-user.target

注意:基于脚本和服务程序可执行权限

启动服务

使用命令systemctl分别启动系统服务ngrokd.servicengrok.service

$ sudo systemctl start ngrok.service