分类 Linux学习 下的文章

背景

目前由于国内备案不支持 .im 域名,导致只能通过海外服务器中转+CDN加速的方式来达成访问,这样的情况下不管是CDN加速还是frp内网穿透,都会导致服务端无法直接获取到真实的IP地址。

思路

通过学习Typecho源码发现,在/var/Typecho/Request.php的 660 行左右,找到了setIp方法,这个方法主要是switch循环,先尝试从$this->getServer(__TYPECHO_IP_SOURCE__)中获取 IP,然后再尝试从$this->getServer('REMOTE_ADDR')中获取IP,而查看getServer相关的代码,发现基本功能就是获取$_SERVER内的相关变量。

解决

通过代码逻辑可以知道,这是官方提前预留出的获取IP地址的方式,显然也是最正确的做法,只要在配置文件提前定义好常量__TYPECHO_IP_SOURCE__的值,那么程序就会优先从这个对应$_SERVER的成员中获取值。
在配置文件/config.inc.php中添加:

/** 定义 IP 来源 */
define('__TYPECHO_IP_SOURCE__', 'HTTP_ALI_CDN_REAL_IP');

这时候后端就能获取到真是的IP地址了,统计工具插件也就可以工作了。

推荐一款Typecho类似于百度统计的本地统计插件Access,还是很好用的。

debian 配置网络和其他Linux类服务器不太一样,debian主要的配置都在 /etc/network/interfaces 文件内,可以配置每个网络接口的IP获取方式和网关地址,同时也是在这里面配置路由转发等。

目前的现状:

enp6s0 连接内网
enp11s0 连接外网

希望的状态:

所有内网的请求通过enp6s0 过来的都走 enp6s0 返回,所有服务器出口的访问和更新,都走 enp11s0 出去,需要在最底部添加一条路由,告诉服务器所有内网的请求走单独的网关(gw)和设备(dev)返回,以下是我的 interfaces文件内的配置:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# Primary
auto enp6s0
iface enp6s0 inet static
address 192.168.69.84
netmask 255.255.255.0

# Second
auto enp11s0
iface enp11s0 inet static
address 192.168.1.102
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 114.114.114.114 114.114.115.115
# 下面表示,所有 192.168 开头的内网请求都走内网的网关和设备返回
up route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.69.254 dev enp6s0

最近组内新购入了一台Mac mini,主要用来当打包机和服务器,考虑到原先的iMac性能不足,所以在采购之初,iOS组同事就将Mac mini的处理器配置到顶格,但无奈内存还是8G,一点点小遗憾,拿到这机器后,我们搁置了一周,后来商量决定还是直接上Docker,以免后续再换新机器又得一堆折腾的事情,所以由我来先折腾安装Docker和在上部署Android所需要的环境。

安装 Docker

macOS上最好用的安装方式还是Homebrew,如何安装Homebrew,参考我之前的博文《终端使用小技巧》

Homebrew 的 Cask 已经支持 Docker for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装:

$ brew cask install docker
//最后会显示安装成功 ↓↓↓↓
🍺  docker was successfully installed!

当然也可以手动下载,就和其他macOS软件一样,是个dmg文件,直接把小鲸鱼拖到Applications里面即可。

安装完以后,从应用中找到 Docker 图标并点击,运行之后,会在右上角菜单栏看到多了一个可爱的鲸鱼图标,这个图标表明了 Docker 的运行状态。

安装 gogs

既然安装好Docker,肯定是为了使用Docker Hub上的gogs镜像创建容器。

步骤

1、拉取gogs镜像

$ docker pull gogs/gogs

2、创建数据挂载目录并设置1000权限

$ sudo mkdir -p ~/Data/Gogs
$ sudo chown 1000 ~/Data/Gogs -R

3、使用run命令绑定端口和挂载目录映射

$ docker run --name gogs -d -p 22:22 -p 3000:3000 -v ~/Data/Gogs:/data gogs/gogs
备注:
--name 容器命名,不能与已存在的重名
-d 将容器跑到后台
-p 用来配置外置端口:内置端口映射关系
-v 用来配置外置目录:内置目录映射关系

4、配置自己的gogs

此处主要就是傻瓜化的页面参数配置,略

5、将配置好的容器打包成镜像

打包镜像比较简单,先找到容器的CONTAINER ID,然后根据CONTAINER ID将容器commit并取个新的镜像名。

//获取[CONTAINER ID]
$ docker ps
//打包成镜像
$ docker commit -m  ""   -a  ""   [CONTAINER ID]  [新镜像名]

以自定义镜像部署

上面提到了gogs的容器打包成自定义镜像,artifactory和jenkins的方式基本类似,我在本地已经全部打包成带-local的自定义镜像,下面的代码显示了如何轻松部署自定义镜像。

$ docker images
REPOSITORY                                TAG                 IMAGE ID            CREATED             SIZE
jenkins-local                             latest              7e534022aff8        7 minutes ago       712MB
maven-local                               latest              f14f7278269b        8 minutes ago       1.03GB
gogs-local                                latest              6af3a7b9a547        About an hour ago   156MB
docker.bintray.io/jfrog/artifactory-oss   latest              b87d8f746026        6 days ago          907MB
gogs/gogs                                 latest              d5b9815c59e1        13 days ago         96.5MB
registry.docker-cn.com/jenkins/jenkins    lts                 806f56c84444        3 weeks ago         703MB
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                        NAMES
03805c16bd1d        e945e5b0afdb        "/entrypoint-artifac…"   2 hours ago         Up 2 hours          0.0.0.0:8081->8081/tcp                       artifactory
d83c9d67e9ec        gogs/gogs           "/app/gogs/docker/st…"   9 hours ago         Up 3 hours          0.0.0.0:22->22/tcp, 0.0.0.0:3000->3000/tcp   gogs
$ docker run --name jenkins -d -p 8080:8080 -p 50000:50000 -v /Users/sungrow/Data/Jenkins:/var/jenkins_home jenkins-local
846200d6f0a184c7f96b94bb9d92d548c5b6e2993dedf60cf9bb36957d733507
$ docker run --name maven -d -p 8081:8081 -v /Users/sungrow/Data/Artifactory:/var/opt/jfrog/artifactory maven-local
1e00e1a243a2119b4ae399e05fe63fa5b7bed1f97299a71c63c7afcdbd26d7bf
$ docker run --name gogs -d -p 22:22 -p 3000:3000 -v /Users/sungrow/Data/Gogs:/data gogs-local
71eeffa65a574b64258cacdfa9948c8c51022fe28af80ed2b5e8b6ecabf63548

时区问题

Docker时区使用的是默认的UTC时间,与我们机器的时间不一致,所以需要对容器内的时间进行同步

//获取[CONTAINER ID]
$ docker ps
//复制宿主时区
$ docker cp /etc/localtime [CONTAINER ID或者CONTAINER NAME]:/etc/localtime

Jenkins由于使用的是openjdk,还需要额外设置下,打开【系统管理】->【脚本命令行】运行下面的命令:

System.setProperty('org.apache.commons.jelly.tags.fmt.timeZone', 'Asia/Shanghai')

在之前的博客树莓派安装frp实现内网穿透,记录了如何搭建frp服务端和如何在树莓派上搭建frp客户端,接着上次的博客,这次我又在我的MacBook Pro上折腾起来了。

下载frpc

Mac因为有UI界面,可以直接鼠标操作,省去敲命令行的繁琐,先去 https://github.com/fatedier/frp/releases 下载最新版本的frpc,特别注意下,Mac用的版本是darwin_amd64结尾的,下载完成后,解压到本地的指定目录,例如我解压到 /usr/local/bin/frpc 目录。

配置开机自启动

解压完成以后为了保证每次开机都能自定启动,需要我们配置frpc.plist文件,并加入到 ~/Library/LaunchAgents/ 这个文件中。

frpc.plist文件内容:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>frpc</string>
    <key>ProgramArguments</key>
    <array>
    <string>/usr/local/bin/frpc</string>
    <string>-c</string>
    <string>/etc/frpc.ini</string>
    </array>
  </dict>
</plist>

最后需要加载生效


 sudo launchctl load -w ~/Library/LaunchAgents/frpc.plist

前言

目前这套博客是搭建在一台树莓派2B上,并且已经稳定运行了好几个月,具体搭建过程在之前的文章树莓派上搭建Typecho小记中都有说明。但搭建在家庭内网的树莓派怎么被外网顺利访问?这个问题的答案就是内网穿透,目前主流的内网穿透方案有很多,物理硬件有:花生棒、公网IP盒子等,开源软件有:Zerotier、n2n、ngrok、Lanproxy以及我选用的frp。

服务端搭建-frps

内网穿透肯定是需要一个固定外网可访问的IP,一般需要租用一台服务器或者VPS,国内服务器一般需要备案,我选用的是搬瓦工VPS,一年10美元,还附赠一个固定IP,可以说非常实惠了。

服务端搭建目前已经整理成一键安装脚本,具体搭建过程如下:
1.安装前查看占用80端口的进程,第二列即为进程号,如果有占用,则kill进程号

# 查看
lsof -i :80|grep -v "PID"
# 杀进程
kill -9 PID

2.安装

wget --no-check-certificate https://raw.githubusercontent.com/bravecheng/ShellScriptList/master/frps/frps.sh -O ./frps.sh
chmod +x ./frps.sh
./frps.sh install

服务端配置文件具体如何配置不再赘述,可以看->官方说明

客户端搭建-frpc

frp是使用go语言开发的,内存占用非常低,而且具有很好的跨平台型,可以在树莓派上完美运行,过了这么久才来写,也是因为确认真的没问题了(* ̄︶ ̄)

运行客户端只需要2个文件,frpc 和 frpc.ini. 这两个文件可以在发布页找到,我们以 frp_0.21.0_linux_arm.tar.gz 为例.

# 获取文件
wget https://github.com/fatedier/frp/releases/download/v0.21.0/frp_0.21.0_linux_arm.tar.gz
# 解压.
tar -zxvf frp_0.21.0_linux_arm.tar.gz

解压后到解压后的文件目录里,可以看到:frpc frps frpc.ini frps.ini 这4个文件,这4个文件只有2个是我们需要的,我们只拷贝这两个就可以了。

# 移动frpc到/usr/local/bin/
mv ./frpc /usr/local/bin/frpc
# 移动frpc.ini到/etc/frpc/
mv ./frpc.ini /etc/frpc/frpc.ini

同样的客户端端配置文件具体如何配置也不再赘述,去看->官方说明

Systemd

大部分 Linux 系统中都内置了Systemd,如果没有可以手动安装Systemd这样我们就能保证在掉电重启后也能正常访问。

安装Systemd

apt-get update
apt-get install systemd
apt-get install systemd-sysv

grub配置

sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash init=/lib/systemd/systemd"

特别注意

在下一个步骤前,我提前说下我遇到的一个问题,加入Systemd的service在我重启树莓派后并没有成功启动,于是开始排查问题,在这个回答中找到了答案,处理方式如下:

1.在frpc.ini [common]配置下,添加

login_fail_exit = false

添加的目的是为了自启动登录失败后不退出,继续重试;

2.frp能正常运行需要2个条件:能联网+服务器和客户端时间正确,所以我们需要树莓派在掉电重启后能自动对时,需要添加napdate.service:

sudo nano /usr/lib/systemd/system/napdate.service

内容如下:

[Unit]
Description=ntpdate
After=network.target

[Service]
Type=simple
User=root
PIDFile=/var/run/ntpdate.pid
ExecStart=/usr/sbin/ntpdate time.windows.com
Restart=on-failure
RestartSec=15s

[Install]
WantedBy=multi-user.target

配置完成后,保存,启用。

systemctl enable napdate.service
systemctl start napdate.service
systemctl status napdate.service

frpc开机自启动

使用Systemd来实现frpc的开机自启动,需要创建frpc.service:

sudo nano /usr/lib/systemd/system/frpc.service

内容如下:

# frpc.service
[Unit]
Description=frpc
After=network.target ntpdate.service

[Service]
Type=simple
User=root
PIDFile=/var/run/frpc.pid
ExecStart=/usr/local/bin/frpc -c /etc/frpc/frpc.ini
Restart=on-failure
RestartSec=15s

[Install]
WantedBy=multi-user.target

简单说明下,After=network.target ntpdate.service 表示该服务在网络加载以及对时服务执行完成才执行,这样保证了frpc的正常执行。配置完成后,保存,启用。

systemctl enable frpc.service
systemctl start frpc.service
systemctl status frpc.service

如果出现启动无效的情况,可以尝试先停止

systemctl stop frpc.service

结束

安装结束后,把树莓派断电试试,如果断电重新上电后一切正常,说明已经配置成功,我这边配置结束后,除了特别注意的那点问题,其余的一切正常。