Why can Nginx Proxy Manager apply SSL to local network addresses?

The short answer is: because SSL certificates are issued based on a domain name, not a network location. The certificate authority (like Let’s Encrypt) only cares that you prove you control the domain, which is done via a public DNS record.

Here’s a detailed breakdown of why and how this works:

1. The Core Principle: Domain Name vs. IP Address

SSL/TLS certificates are bound to domain names (e.g., myhomeserver.example.com), not to public or private IP addresses (e.g., 192.168.1.100). A Certificate Authority (CA) like Let’s Encrypt issues a certificate for a domain after verifying you own it. It doesn’t matter if that domain name resolves to a public IP (203.0.113.10) or a private one (192.168.1.100).

2. The Validation Method: How NPM “Proves” Ownership

To get a certificate, NPM must prove to the CA that it controls the domain. It does this using one of the ACME protocol challenges. For internal networks, the DNS-01 challenge is the most common and reliable method:

  • How it works: The CA gives NPM a unique token. NPM instructs you (or an automated API script) to create a specific TXT record in your domain’s DNS zone (e.g., _acme-challenge.myhomeserver.example.com. IN TXT "gfj8X7...").
  • Why it works for local networks: The CA checks the DNS record from the public internet. This validation happens entirely in DNS, completely independent of your internal network’s IP scheme. Once validated, the certificate is issued.

3. How Your Devices Trust the Certificate

Once NPM has the certificate, it presents it to any client (web browser, app) that connects to it.

  • The client checks if the domain name in the URL matches the domain name in the certificate.
  • The client then checks if the certificate is signed by a trusted CA (like Let’s Encrypt).
  • Since Let’s Encrypt is trusted by virtually all operating systems and browsers, the connection is secured with a green padlock, even though the traffic is only going to your local router.

The Practical Setup: A Typical Example

Let’s say you have a server at 192.168.1.100. Here’s how you set it up:

  1. Buy a Domain: You own a domain (e.g., example.com).
  2. Create a DNS Record: In your domain’s DNS settings (at your registrar like Cloudflare or Namecheap), you create an A record pointing your chosen subdomain to your home’s public IP address.
    • Record Type: A
    • Name: myserver (or home, nas, etc.)
    • Value: Your.Public.IP.Address
  3. Port Forwarding: On your home router, you forward ports 80 (HTTP) and 443 (HTTPS) to the internal IP of your Nginx Proxy Manager server (192.168.1.100).
  4. Configure NPM:
    • Add a Proxy Host in NPM.
    • Domain Names: myserver.example.com
    • Scheme: http
    • Forward IP/ Hostname: 192.168.1.50 (the actual IP of your internal service, like WordPress or Jellyfin).
  5. Request SSL Certificate:
    • In the SSL tab for that proxy host, request a new certificate.
    • Use the DNS Challenge and provide your DNS provider’s API credentials. NPM will automatically create and delete the required TXT record to prove ownership.
    • Enable “Force SSL” and “HTTP/2”.

What Happens When You Visit?

  • From Outside Your Network: You go to https://myserver.example.com. Your DNS resolves this to your public IP. Your router forwards the HTTPS request to NPM on 192.168.1.100. NPM presents the valid certificate for myserver.example.com and proxies the request to your internal service.
  • From Inside Your Network: The process is exactly the same! Your device makes a DNS request for myserver.example.com, which resolves to your public IP. Your router sees that the traffic is going to its own public IP (a loopback) and handles it internally, sending the request back to itself and then to NPM. This is called NAT Loopback or Hairpin NAT. NPM again presents the valid certificate.

Important Considerations

  • NAT Loopback Requirement: For this to work seamlessly from inside your network, your router must support NAT Loopback. Most modern consumer routers do, but some don’t. If yours doesn’t, you can work around it by configuring local DNS on your network (e.g., using Pi-hole) to resolve myserver.example.com directly to NPM’s local IP (192.168.1.100), bypassing the public IP entirely.
  • Security: You are exposing a entry point to your internal network. It is critical to:
    • Keep NPM and your services updated.
    • Use strong passwords.
    • Consider adding additional authentication layers (like the built-in Access Lists in NPM) for sensitive services.

In summary, NPM applies SSL from the local network because the trust is established by a public DNS record and a certificate from a globally trusted authority, not by the network path the request takes.

Continue ReadingWhy can Nginx Proxy Manager apply SSL to local network addresses?

Setup Chinese input on ChacyOS

Install fcitx5 with the following commands:

sudo pacman -S fcitx5-im 
sudo pacman -S fcitx5-chinese-addons  fcitx5-rime

Add the following config lines into /etc/environment:

# /etc/environment
GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
SDL_IM_MODULE=fcitx

Reboot the system.

Continue ReadingSetup Chinese input on ChacyOS

How to expand root partition in Openwrt VM

First, add space into the Openwrt VM. Taking proxmox as an example, go to Openwrt VM -> hardware -> hard disk -> disk -> action -> resize.

Second, copy and paste the follwing into a sh file expand-root.sh:

# Configure startup scripts                                                                               
cat << "EOF" > /etc/uci-defaults/70-rootpt-resize                                                         
if [ ! -e /etc/rootpt-resize ] \                                                                          
&& type parted > /dev/null \                                                                              
&& lock -n /var/lock/root-resize                                                                          
then                                                                                                      
ROOT_BLK="$(readlink -f /sys/dev/block/"$(awk -e \                                                        
'$9=="/dev/root"{print $3}' /proc/self/mountinfo)")"                                                      
ROOT_DISK="/dev/$(basename "${ROOT_BLK%/*}")"                                                             
ROOT_PART="${ROOT_BLK##*[^0-9]}"                                                                          
parted -f -s "${ROOT_DISK}" \                                                                             
resizepart "${ROOT_PART}" 100%                                                                            
mount_root done                                                                                           
touch /etc/rootpt-resize                                                                                  
reboot                                                                                                    
fi                                                                                                        
exit 1                                                                                                    
EOF                                                                                                       
cat << "EOF" > /etc/uci-defaults/80-rootfs-resize                                                         
if [ ! -e /etc/rootfs-resize ] \                                                                          
&& [ -e /etc/rootpt-resize ] \                                                                            
&& type losetup > /dev/null \                                                                             
&& type resize2fs > /dev/null \                                                                           
&& lock -n /var/lock/root-resize                                                                          
then                                                                                                      
ROOT_BLK="$(readlink -f /sys/dev/block/"$(awk -e \                                                        
'$9=="/dev/root"{print $3}' /proc/self/mountinfo)")"                                                      
ROOT_DEV="/dev/${ROOT_BLK##*/}"                                                                           
LOOP_DEV="$(awk -e '$5=="/overlay"{print $9}' \                                                           
/proc/self/mountinfo)"                                                                                    
if [ -z "${LOOP_DEV}" ]                                                                                   
then                                                                                                      
LOOP_DEV="$(losetup -f)"                                                                                  
losetup "${LOOP_DEV}" "${ROOT_DEV}"                                                                       
fi                                                                                                        
resize2fs -f "${LOOP_DEV}"                                                                                
mount_root done                                                                                           
touch /etc/rootfs-resize                                                                                  
reboot                                                                                                    
fi                                                                                                        
exit 1                                                                                                    
EOF                                                                                                       
cat << "EOF" >> /etc/sysupgrade.conf                                                                      
/etc/uci-defaults/70-rootpt-resize                                                                        
/etc/uci-defaults/80-rootfs-resize                                                                        
EOF     

Last, run the sh file: ./expand-root.sh

Continue ReadingHow to expand root partition in Openwrt VM

Openwrt衍生固件的对比分析

以下是五个最常用的OpenWrt固件的对比分析,帮助你选择最适合的固件。

1. 官方OpenWrt固件
历史背景:
OpenWrt是最早的嵌入式Linux路由操作系统之一,起源于2004年对Linksys WRT54G路由器的逆向工程。经过多年发展,已成为功能强大、高度可定制的开源项目,社区活跃且更新频繁。
优点:
高度灵活,支持多种设备架构。
软件生态丰富,支持数千个插件。
安全性高,内核持续更新。
缺点:
学习曲线陡峭,依赖命令行配置。
稳定性风险较高,新功能可能导致兼容性问题。
适合用户:
技术专家、开发者或需要深度定制功能的用户。
官方网站:
https://openwrt.org/
安装方法:
https://openwrt.org/docs/guide-user/installation/generic.flashing

2. ImmortalWrt
历史背景:
由OpenWrt社区分支而来,强调开源和稳定性,中文社区支持度高。开发团队活跃,更新频率接近官方但更注重优化。
优点:
开源纯净,无闭源组件。
硬件兼容广,支持多种设备。
中文友好,提供中文文档和社区支持。
缺点:
功能较少,预装插件有限。
依赖社区维护,部分功能需第三方开发者更新。
适合用户:
追求稳定性与开源原则的中高级用户,尤其是中文环境下的技术爱好者。
官方网站:
https://immortalwrt.org/
安装方法:
https://immortalwrt.org/docs/guide-user/installation/generic.flashing

3. Lean固件(LEDE分支)
历史背景:
由国内开发者Lean维护,最初基于OpenWrt的LEDE分支,后发展为独立项目。以集成丰富插件和闭源驱动著称。
优点:
功能丰富,预装科学上网、多拨等插件。
性能优化,支持WiFi 6/7等新协议。
缺点:
闭源组件,可能存在安全隐患。
更新滞后,稳定性依赖维护者经验。
适合用户:
需要多功能集成且不介意闭源组件的进阶用户,尤其适合网络优化玩家。
官方网站:
https://github.com/coolsnowwolf/lede
安装方法:
https://github.com/coolsnowwolf/lede/wiki

4. iStoreOS
历史背景:
由原koolshare团队开发,主打易用性,提供类应用商店的交互界面,降低OpenWrt使用门槛。
优点:
新手友好,图形化界面简化插件安装。
稳定性高,基于官方代码优化。
缺点:
功能受限,深度定制能力弱于原版。
硬件支持少,主要适配x86软路由和部分热门机型。
适合用户:
普通家庭用户或小白用户,追求即插即用,无需复杂配置。
官方网站:
https://www.istoreos.com/
安装方法:
https://www.istoreos.com/docs/installation

5. X-Wrt
历史背景:
专注于界面优化的OpenWrt分支,改进原版Luci的交互体验,同时保持代码接近官方。
优点:
界面美观,提供更直观的Web管理界面。
兼容性强,支持多种设备。
缺点:
插件生态弱,依赖官方软件源。
维护依赖个人,更新频率受开发者个人时间影响。
适合用户:
希望平衡界面友好性和OpenWrt原生功能的用户。
官方网站:
https://x-wrt.com/
安装方法:
https://x-wrt.com/docs/guide-user/installation/generic.flashing

综合分析与结论
最佳稳定性与开源性:ImmortalWrt
在开源、更新频率和中文支持上表现均衡,适合大多数技术用户。
最佳易用性:iStoreOS
对新手最友好,适合家庭用户快速部署。
最佳功能扩展:Lean固件
集成插件丰富,满足高级需求,但需接受闭源组件的风险。
最佳原生体验:官方OpenWrt
适合开发者或需要完全控制设备的专家用户。
最佳界面优化:X-Wrt
适合希望简化操作但保留灵活性的中间用户。

最终结论
若需推荐一个“最好”的固件,需结合用户需求:
普通用户首选iStoreOS,因其易用性和稳定性;
进阶用户推荐ImmortalWrt,平衡了开源、功能与社区支持;
极客玩家则适合官方OpenWrt或Lean固件,以发挥最大定制潜力。

Continue ReadingOpenwrt衍生固件的对比分析