分类
Linux

在64位Manjaro ARM上使用fcitx-rime

博主在今年6月份的时候出于支持ARM无聊购买了一台Pinebook Pro,但一拿到手就发现屏幕上出现了9个坏点败了兴致。

直到昨天屏幕面板的替换件到货,博主才正式开始Pinebook Pro的体(Cai)验(Keng)之旅。

结果发现安装好的fcitx-rime无法使用。。。

将中州韻添加到当前输入法列表后却发现死活无法调出,且一旦切换到中州韻,该输入法的选项就会从列表中消失。

在终端中启动fcitx的时候发现系统无法加载fcitx-rime.so,并提示

/usr/lib/libtcmalloc.so.4: 无法在静态 TLS 块中分配内存

英文环境下提示

/usr/lib/libtcmalloc.so.4: cannot allocate memory in static TLS block

貌似是tcmalloc在64位arm(aarch64)架构上有坑,导致了fcitx-rime.so无法加载。

解决方案就很简单了,找出rime中用了tcmalloc的库,并重新编译一份使用malloc的版本。在Archlinux的官网上查询到,fcitx-rime使用了rime的librime库,然后librime使用了leveldb,leveldb又依赖了gperftools。而gperftools就可以说是tcmalloc在archlinux中的本体了。下载leveldb的PKGBUILD文件,将gperftools从依赖中删除,卸载系统中的gperftools后makepkg -s -i重新构建并安装leveldb。

可是事情还没完。。。Rime是跑起来了,但朙月拼音·简化字打出来却全是繁体。。。

用终端打开fcitx继续看输出信息,系统提示

opencc config not found: /usr/share/rime-data/opencc/t2s.json

原来朙月拼音·简化字的码表依旧是繁体字,只是在输出的时候通过opencc简转繁。但按照字面意义上理解,应该是/usr/share/rime-data/opencc/t2s.json这个文件不存在,可是这个文件确确实实又在那里。

与opencc自己在/usr/share/opencc目录下的t2s.json配置文件对比,发现我从archlinux.org上拷贝PKGBUILD自己编译的fcitx-rime中所带的配置文件有错误。opencc自带的t2s.json配置文件file项中所出现的文件都是以.ocd2结尾的,而rime所带的opencc配置文件是以.ocd结尾的。将/usr/share/rime-data/opencc目录里的配置文件用/usr/share/opencc里的配置文件替换掉,重新加载rime配置或重新启动fcitx后解决问题。

分类
Linux 硬件 网络

DD-WRT使用radvd配置IPv6后桥接AP疯狂掉线

继Linksys EA6400后,为了能够在整个公寓里享受200M的宽带,博主又在eBay上捡了个Linksys EA6500 V1。可通电插上网线后博主却发现,连接在AP上的设备疯狂掉线。一开始博主还以为是捡垃圾翻车了,但在后来的观察中发现事情好像并不是那么一回事。

先说一下两个路由器的设置,EA6500到家后就被我刷成了DD-WRT,然后在设置中禁用掉了WAN口,将WAN与LAN桥接在一起作为LAN使用并禁用掉了路由功能。作为主路由的EA6400使用radvd来给局域网中的设备配置IPv6地址。

连接在主路由上的设备没有任何问题,连接稳定,也能正常的获取IPv6地址。而连接在作为AP的EA6500上的设备就会间歇性的掉线。在我的Pixel上表现为连接上AP一段时间后,WiFi断开并迅速重连,但在我的Chromebook上就表现的比较有意思了。Chromebook在连接上AP后,会间歇性的无法访问网络,但此时WiFi并没有断开,两个路由器的管理页面也无法访问,一段时间后网络恢复,但IPv6地址丢失。结合之前修改radvd配置后连接在主路由的Pixel也会掉线重连这个现象,猜测可能是NDP在AP上出了啥问题。

在尝试修改各种EA6500上的网桥广播配置无果后,找到了通过Dnsmasq来代替radvd配置IPv6网络的方法,完美解决掉线。

首先禁用radvd,然后在DD-WRT设置中的Services-Services-Dnsmasq-Additional Dnsmasq Options中填入以下配置:

dhcp-range=::,constructor:br0,ra-stateless,1800
dhcp-option=option6:dns-server,[2606:4700:4700::1111],[2606:4700:4700::1001]
enable-ra
quiet-ra
quiet-dhcp
quiet-dhcp6

例子中的[2606:4700:4700::1111]和[2606:4700:4700::1001]为CloudFlare所运营的1.1.1.1 DNS

将设备重新连接WiFi后即可正常工作

分类
Linux 硬件 网络

Linksys EA6400刷魔改CFE并清空nvram后无法启动DD-WRT

由于贫穷,初来德国时为了便宜而又快乐的网上冲浪,我在Amazon上捡了个EA6400的垃圾。为了方便刷机,就按照教程刷入了魔改版的CFE,结果在清空nvram后ddwrt死活启动不了,刷回官方固件不停报错,TTL调试也没看出啥结果。

在后续的折腾过程中发现,在CFE中清空nvram会删掉DD-WRT启动所需要的关键参数,而梅林可以在启动的时候重新写入这些参数。

那么解决方法就是:

先刷入梅林,然后不清空nvram刷入ddwrt,此时ddwrt便可正常工作。以后再恢复出厂设置,使用DDWRT管理界面中的恢复出场设置即可,千万别手贱用CFE中的清空nvram功能。

分类
Linux

让Zsh不保存某条命令的历史记录

最近博主心血来潮将Shell从Bash给切换到了Zsh。然后我就发现我最常用的命令之一history -c在Zsh下没法用了。。。

这让有轻度强迫症的博主十分不爽,随即便Google了一下让Zsh不保存某条命令历史记录的方法并在此记录下来。

在Zsh的配置文件.zshrc中加入

setopt histignorespace

在以后输入命令时,如果不想保存某条命令的历史记录,在命令前加一个空格即可。

分类
Linux

GRUB菜单密码

为GRUB菜单增加密码保护,在系统启动或修改GRUB引导选项时要求输入密码。

参考ArchWikiGRUB官方文档,输入下列命令生成密码密文:

grub-mkpasswd-pbkdf2

得到类似输出:

[hacc@Hacc-Laptop ~]$ grub-mkpasswd-pbkdf2
输入口令:
Reenter password: 
PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.B8E131613525DCA838924A60E71C6CBB374D94EC58B24D32B385B7C744060A14D709A50A0CC0218579068E6A62CBCEB6BC4E2D9157DE31A881219F0B37DA370A.DD2E8E488C862597EF88C4445BA6DDBEDB75B5654D2E2690C2152B7C45FB49993F91B4DC177B94046FFBABBBDD2A9DFF61AFC4CB7A14B954C5FC9365B4271829

修改/etc/grub.d/40_custom在文件尾部加入:

set superusers="username"
password_pbkdf2 username <password>

将username换成你的用户名,如root,将<password>换成grub-mkpasswd-pbkdf2命令生成的密码,修改好后类似如下:

set superusers="root"
password_pbkdf2 root grub.pbkdf2.sha512.10000.B8E131613525DCA838924A60E71C6CBB374D94EC58B24D32B385B7C744060A14D709A50A0CC0218579068E6A62CBCEB6BC4E2D9157DE31A881219F0B37DA370A.DD2E8E488C862597EF88C4445BA6DDBEDB75B5654D2E2690C2152B7C45FB49993F91B4DC177B94046FFBABBBDD2A9DFF61AFC4CB7A14B954C5FC9365B4271829

重新生成GRUB配置文件即可

sudo grub-mkconfig -o /boot/grub/grub.cfg

当然,为GRUB菜单设置密码也只是防君子不防小人,若别人真心想搞你,在能够物理访问你的设备的情况下这种密码是然并卵的。

分类
Linux

反代Duden

由于Duden的官方网站上引用了一些被墙的资源,导致Duden访问起来巨慢无比,查词巨不方便。博主便决定用Nginx的“反向代理”功能建立一个Duden的镜像站。

先在Freenom上申请一个免费的顶级域名

为镜像站建立一个目录

sudo mkdir /usr/share/nginx/html/ddproxy

在Nginx配置文件中加入以下代码(镜像站首页):

server {
        listen [::]:443;

        ssl        on;
        ssl_certificate         ssl/ddproxy.cf.pem;
        ssl_certificate_key     ssl/ddproxy.cf.key;

        server_name    ddproxy.cf www.ddproxy.cf;
        access_log     /var/log/nginx/nginx.vhost.access.log;
        error_log      /var/log/nginx/nginx.vhost.error.log;
        location / {
                root   /usr/share/nginx/html/ddproxy;
        }
}

Duden反向代理:

server {
        listen [::]:443 ssl http2;

        ssl        on;
        ssl_certificate         ssl/ddproxy.cf.pem;
        ssl_certificate_key     ssl/ddproxy.cf.key;

        server_name    dictacceleration.ddproxy.cf;
        access_log     /var/log/nginx/nginx.vhost.access.log;
        error_log      /var/log/nginx/nginx.vhost.error.log;
        root   /usr/share/nginx/html/ddproxy;
        location / {
                proxy_redirect https://www.duden.de/ /;
                proxy_cookie_domain duden.de dictacceleration.ddproxy.cf;
                proxy_pass https://www.duden.de;
                proxy_set_header X-Real-IP $realip_remote_addr;
                proxy_set_header X-Forwarded-For $realip_remote_addr;
                proxy_set_header Host "www.duden.de";
                proxy_set_header Accept-Encoding "";
                proxy_set_header User-Agent $http_user_agent;
                proxy_set_header Accept-Language "zh-CN";
                sub_filter www.duden.de dictacceleration.ddproxy.cf;
                sub_filter ajax.googleapis.com ajax.ddproxy.cf;
                sub_filter rs.epoq.de none.ddproxy.cf;
                sub_filter static.site24x7rum.com none.ddproxy.cf;
                sub_filter cdn-a.yieldlove.com none.ddproxy.cf;
                sub_filter d29pb5sqvxbrp8.cloudfront.net none.ddproxy.cf;
                sub_filter_once off;
        }
}

这里用sub_filter替换字符串,并将一部分被墙的非重要资源给导向none.ddproxy.cf这个域名,该域名被解析到127.0.0.1[::1]。以此来变相阻止浏览器加载被墙资源,加速页面加载。

ajax.googleapis.com反代:

server {
        listen [::]:443 ssl http2;

        ssl        on;
        ssl_certificate         ssl/ddproxy.cf.pem;
        ssl_certificate_key     ssl/ddproxy.cf.key;

        server_name    ajax.ddproxy.cf;
        access_log     /var/log/nginx/nginx.vhost.access.log;
        error_log      /var/log/nginx/nginx.vhost.error.log;
        root   /usr/share/nginx/html/ddproxy;
        location / {
                proxy_redirect https://ajax.googleapis.com/ /;
                proxy_cookie_domain ajax.googleapis.com ajax.ddproxy.cf;
                proxy_pass https://ajax.googleapis.com;
                proxy_set_header X-Real-IP $realip_remote_addr;
                proxy_set_header X-Forwarded-For $realip_remote_addr;
                proxy_set_header Host "ajax.googleapis.com";
                proxy_set_header Accept-Encoding "";
                proxy_set_header User-Agent $http_user_agent;
                proxy_set_header Accept-Language "zh-CN";
                sub_filter ajax.googleapis.com ajax.ddproxy.cf;
                sub_filter_once off;
        }
}
分类
Linux

让Nginx获取访问者的真实IP

这项特性需要Nginx模块ngx_http_realip_module来实现

参考Cloudflare官方文档在配置文件的http块中加入

set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

# use any of the following two
real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;
分类
Linux

在Vultr上的Archlinux配置IPv6

一直奉行「生命在于折腾」的博主在VPS购买后没多久便将系统换成了Archlinux,配置时为了省事就用了dhcpcd自动配置了IP地址。

自动配置的IPv4是完美的,可自动配置的IPv6就出事了。。。之前一直没有用过IPv6做过网站,直到最近脑抽突然想用Cloudflare的IPv6网关时才将问题暴露出来。

服务器可以ping外界IPv6主机,但外界IPv6主机却没法ping服务器。用systemctl status dhcpcd查看dhcpcd的日志后发现,这玩意自动获取的IPv6地址和Vultr给的固定IPv6地址不是一个地址。。。

man DHCPCD.CONF查询,得到dhcpcd的静态地址配置方法。在/etc/dhcpcd.conf的尾部加入如下内容

interface eth0 #网卡名
static ip6_address= #你的静态IPv6地址

然后sudo systemctl restart dhcpcd重启dhcpcd后就OK了。


然而博主在配置Nginx时并没有监听IPv6地址,因此想要使用Cloudflare的IPv6网关还得要在配置文件中的server块中有

listen [::]:80;

或者是

listen [::]:443 ssl http2;
分类
Linux

Web服务IP白名单

孤陋寡闻的博主某天突然知道还可以通过“全网扫描”这种骚操作来获取CDN背后网站的真实IP。于是乎为了(hao)增(wan)强网站的安全性,博主开始折腾通过白名单来屏蔽全网扫描大法。

博主首先想到的是通过Nginx来屏蔽。

首先通过https://www.cloudflare.com/ips/来get到Cloudflare的IP段。

将allow指令添加到配置文件的http块下,依次添加Cloudflare的IP段。

allow 103.21.244.0/22;
…
allow 2400:cb00::/32;
…

然后再添加

deny all;

访问源站,服务器确实返回了403,可这是在https握手之后才返回的。。。

证书暴露了。。。

然后想到让Nginx返回444,说不定可以在握手前断开与白名单外主机的连接。

参考Ilham Sulaksono的回答后,在配置文件的http块中加入

geo $remote_addr $allowed_trafic {
default false;
103.21.244.0/22 true;
…
2400:cb00::/32 true;
…
}

来添加Cloudflare的IP段

在每个server块下添加

if ( $allowed_trafic = 'false'){
return 444;
}

重启Nginx后发现。。。

依然是在握手后才断开连接。。。

好吧,服气。。。

看来只能用iptables屏蔽了。。。

依次输入

sudo systemctl enable iptables
sudo systemctl enable ip6tables

启用iptables

然后输入

sudo touch /etc/iptables/iptables.rules
sudo touch /etc/iptables/ip6tables.rules

新建一个空配置文件

再依次输入

sudo systemctl start iptables
sudo systemctl start ip6tables

启动iptables

输入sudo bash提权

参考Frank Rietta的文章还有Cloudflare的文档用root权限执行以下指令来将Cloudflare的IP段以及本地回环地址添加进iptables。

for i in `curl https://www.cloudflare.com/ips-v4`; do iptables -I INPUT -p tcp -s $i --dport http -j ACCEPT; done
for i in `curl https://www.cloudflare.com/ips-v4`; do iptables -I INPUT -p tcp -s $i --dport https -j ACCEPT; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ip6tables -I INPUT -p tcp -s $i --dport http -j ACCEPT; done
for i in `curl https://www.cloudflare.com/ips-v6`; do ip6tables -I INPUT -p tcp -s $i --dport https -j ACCEPT; done

然后再输入下列指令来丢弃掉白名单外主机的数据包

iptables -A INPUT -p tcp --dport http -j DROP
iptables -A INPUT -p tcp --dport https -j DROP
ip6tables -A INPUT -p tcp --dport http -j DROP
ip6tables -A INPUT -p tcp --dport https -j DROP

此时设置就已经完成了,可设置还没有保存,还需要输入

iptables-save > /etc/iptables/iptables.rules
ip6tables-save > /etc/iptables/ip6tables.rules

将设置保存到配置文件

分类
Linux

Nginx的WordPress伪静态配置

参考Nginx官方文档WordPress官方文档在location块中加入

try_files $uri $uri/ /index.php?$args;