Category: Uncategorized

  • One year later, my statement on Twitter/X

    If you are wondering why my Twitter/X account @_neelc is blank, it’s because of this reason: X is basically KiwiFarms, but mainstream: a platform to spread hate.

    I have gotten politically conservative ads despite following tons of LGBTQ+ accounts, having a trans brother, and being non-binary and aromantic myself.

    Pre-Elon Musk, I used to look up to Twitter as a company. Now, Twitter is a dumpster fire. The posts aren’t even high quality, just “low effort” garbage.

    The only reason why I won’t nuke the account is because my DuckDNS dynamic DNS login is tied to Twitter. That only because Reddit login was nuked ages ago (well before the infamous API changes).

    In hindsight, I should’ve used GitHub, but nobody can predict the future. I couldn’t predict that a literal Nazi will buy an important social platform, very less one I relied on heavily until last year.

    As of now, I have deleted all my Tweets and replies. I don’t advocate use of Twitter and neither should you.

    Nowadays, the most reliable way to follow me is on the Fediverse (a.k.a. “Mastodon”) at @neel@neelc.org. And yes, I self-host “Mastodon” (technically GoToSocial) alongside my email.

    I will certainly miss non-tech accounts, especially those who couldn’t figure out Mastodon, very less run their own server like me. I guess there’s TikTok, not that TikTok is too great, but sadly now much better than Elon X.

  • Taming Fan Noise on HPE Gen11 Servers and Third-Party NVMe Drives

    I recently got a HPE ProLiant ML110 Gen11. While it cost far more than the previous generation thanks to COVID-19, the trade war, and supply chain issues, it is still an excellent server.

    One thing with HPE servers is that by default, if you use a third-party NVMe drive, or any PCI Express card that isn’t blessed by HPE, the fan becomes very loud. By very loud, I mean I can hear it from a shut closet. I even had some family come over and complain how loud it is.

    To add to the fire, I’m planning to move back to NYC from Seattle (no timeframe however) and while NYC is noisy, I don’t want to hear buzzing noise when I sleep especially in a small apartment.

    To make the server quiet with a third-party NVMe drive, you can use this cURL command on the iLO “Redfish” API:

    curl --request PATCH --url 'https://[ILO_IP]/redfish/v1/Chassis/1/Thermal/' --user '[ILO_USER]' --header 'content-type: application/json' --insecure --data '{"Oem": {"Hpe": {"FanPercentAdjust": 50}}}' 

    Replace ILO_IP with the iLO IP address and ILO_USER with the iLO Administrator (usually Administrator but for me I add a neel account).

    You can also replace the 50 with a higher or lower value to make it louder or quieter respectively, but don’t go so quiet to make your server overheat. HPE Redfish works a bit differently than what us humans are used to. Setting the number to 50 would make the server with 50% less fan noise, while 25 would mean normal fan noise (the default) and 0 means 50% more fan noise.

    After that, the server is pretty quiet, whether the closet is open or shut.

    Credit: @Itzikbenabu from the HPE forums.

    What about HPE amsd?

    While a common solution is HPE’s amsd, that didn’t work for me with NVMe drives. It is more for SATA and SAS drives.

    iLO also couldn’t see the Rocky Linux version of amsd, but the RHEL version was seen by iLO fine even on Rocky. Even when iLO sees amsd, the server was still noisy before I ran the above Redfish command.

  • Forwarding Ports 80 and 443 on OPNsense Correctly

    If you’re like me and run your own home server, you might find yourself needing to forward TCP ports 80 and 443 on your router. I recently changed my firewall from OpenWrt to OPNsense and obviously needed to forward ports 80 and 443 to my home server.

    By default, OPNsense tries to listen it’s web UI on all ports, well sort of. Many suggestions online say you should change the port the web UI listens on. I’ll tell you that suggestion doesn’t work for me at all.

    If you need to port forward TCP ports 80 and 443 correctly, here’s what you need to do:

    1. Log into your OPNsense web portal. Most likely it’s 192.168.1.1 unless you changed it like me.

    2. Go to Firewall -> Settings -> Advanced on the sidebar

    3. In the Network Address Translation section, check Reflection for port forwards and Automatic outbound NAT for Reflection and then click Save

    4. Go to NAT -> Port Forward and add or edit your existing port forwards for 80 and 443

    5. In the NAT reflection section, select Enable

    6. When it asks you to save settings, select Apply changes


    And that my friend is how to correctly forward Port 80 and 443 in OPNsense.

  • Bypassing Gmail's spam filters with ChatGPT

    If you haven’t been living under a rock, you probably already know what ChatGPT is.

    I am an operator of high bandwidth Tor exit relays, and with that, I get a lot of abuse complaints. Combined with the fact that I have ai lease on a “/24” of IPv4 space, basically a block of 256 IP addresses, I have the IP space’s contact to my LLC’s email address.

    What does this have to do with ChatGPT, you may ask? Last night, I was sending responses to abuse complaints using Tor’s exit boilerplates, and while I run my own email server, I had to email Abusix which used Gmail/Google Workspace.

    The standard Tor boilerplate below was caught by Gmail as “spam”:

    The IP address in question is a Tor exit node. https://www.torproject.org/overview.html

    There is little we can do to trace this matter further. As can be seen from the overview page, the Tor network is designed to make tracing of users impossible. The Tor network is run by some 5000 volunteers who use the free software provided by the Tor Project to run Tor routers. Client connections are routed through multiple relays, and are multiplexed together on the connections between relays. The system does not record logs of client connections or previous hops.

    This is because the Tor network is a censorship resistance, privacy, and anonymity system used by whistle blowers, journalists, Chinese dissidents skirting the Great Firewall, abuse victims, stalker targets, the US military, and law enforcement, just to name a few. See https://www.torproject.org/about/torusers.html.en for more info.

    Unfortunately, some people misuse the network. However, compared to the rate of legitimate use (the IP range in question processes nearly a gigabit of traffic per second), abuse complaints are rare: https://support.torproject.org/abuse/.

    I was worried my IPs were blacklisted, so I sent emails to a few gmail.com addresses and they all went through fine, so it probably is Gmail thinks the standard Tor response is “spam” when it’s not.

    Condidering that ChatGPT is the hottest thing right now, I immediately signed up for OpenAI and asked it to reword the above response. I got this:

    It appears that the IP address in question is associated with a Tor exit node, as outlined on the Tor Project’s overview page: https://www.torproject.org/overview.html. Due to the nature of the Tor network, which is designed to protect users’ anonymity and privacy by routing their internet traffic through multiple layers of encryption and relays, it is difficult, if not impossible, to trace the source of this matter further. The Tor network is run by a community of approximately 5000 volunteers who use the free software provided by the Tor Project to operate Tor routers. Connections made by users are routed through multiple relays and are multiplexed together on the connections between relays. The system does not record logs of client connections or previous hops.

    The Tor network is a censorship resistance, privacy, and anonymity system that is used by a variety of individuals and groups such as whistle-blowers, journalists, Chinese dissidents, abuse victims, and law enforcement agencies. For more information on the various ways in which the Tor network is used, please visit: https://www.torproject.org/about/torusers.html.en

    It is worth noting that while the Tor network is used for a variety of legitimate purposes, it is also sometimes misused by individuals or groups for illegal or malicious activities. However, compared to the rate of legitimate use, which is substantial (the IP range in question processes nearly a gigabit of traffic per second), reports of abuse are relatively infrequent. For more information on abuse complaints and how they are handled, please visit: https://support.torproject.org/abuse/

    While it is longer, it got through Gmail’s spam filters fine.

    I had a legitimate use of ChatGPT, I was stuck with either leave it without a response, hastily write a response personally at 11 PM, or have ChatGPT reword the Tor boilerplate so I can go to bed.

    I’m no AI or machine learning expert so I don’t know how it works. But I am also worried that spammers could use ChatGPT to get around Gmail and Outlook’s spam filters. What about Yahoo or self-hosted/on-prem servers who may not have the same AI talent as Google or Microsoft? (Disclaimer: I presently work at Microsoft 365, but as likely inferred earlier don’t use Outlook/Exchange Online outside of work).

    I already get “spam” coming from @gmail.com or @outlook.com emails, mainly since I am subscribed to FreeBSD’s mailing lists and I am too lazy to train rspamd.

    But assuming that doomsday scenario mentioned above doesn’t happen, ChatGPT can be my go-to place to write Tor boilerplates when needed.

  • How to clone your Calix GPON ONT (Optical Network Terminal)

    UPDATE: I haven’t had CenturyLink in quite a while as I have moved eastwards. CenturyLink has rebranded their fiber service to “Quantum Fiber” which I have no experience with. This guide may or may not apply to the newer “Smart NID” models.

    WARNING: This guide is for instructional purposes only. I am not responsible for any damages caused by this guide. This guide may violate your ISP’s terms of service and is possibly illegal. Proceed at your own risk.

    When I got CenturyLink Fiber at my current residence, I initially had an issue which looked like “latency spikes and packet loss”.

    Little did I know that the ONT (Optical Netowrk Terminal) given, a Calix 716GE-I R2 has a hard cap of 16384 TCP sessions, not unlike AT&T Fiber’s forced routers. Even lesser known that unlike AT&T’s infamous “BGW320” model, it’s very easy to clone Calix ONTs with just a JTAG cable, and other Calix models don’t have the issue. I cloned my ONT to a Calix 803G which has been literally perfect without issue since I took the plunge.

    However, this guide isn’t for you if:

    • You have CenturyLink DSL

    • You have CenturyLink Fiber with another ONT vendor (e.g. Adtran)

    • You have AT&T Fiber with a BGW320 and want to “bypass”

    • You are replacing a Calix XGS-PON, NG-PON2, EPON or 10G-EPON ONT with a GPON ONT, or vice-versa

    • Your original ONT is non-Calix model.

    This guide may work with non-CenturyLink ISPs using Calix gear, however.

    So you want to clone your ONT?

    Pre-requisites

    You need the following devices information:


    • Original, ISP-provided Calix ONT with the ONU MAC and FSAN Serial ready



    • If required, your GPON Password. CenturyLink doesn’t use this



    • Calix ONT being cloned to



    • JTAG serial adapter


    About the JTAG adapter, the CP2102 models are recommended. Other models have had issues with Calix’s JTAG console.

    Cloning the ONT

    Now for the fun part.

    First off, you need to open your ONT.

    For the 803G (the destination ONT), these images should be self-explanatory.

    Calix ONT Part 1

    Calix ONT Part 2

    Calix ONT Part 3

    Calix ONT Part 4

    When you are inside, connect the JTAG.

    Calix ONT JTAG

    Note: The TX should go to your JTAG RX and vice-versa.

    Image source: fire-foo.com.

    When you connected your JTAG header pins, open a serial console (e.g. cu or PuTTY), plug in the power while hitting ESC on your keyboard repeatedly.

    When you are on the CFE> prompt, type b and press enter.

    Press enter for most of the values, except the Base MAC Address and GPON Serial Number which should be the ONU MAC and FSAN Serial respectively from your source ONT.

    Some ISPs may need a GPON password, but it seems CenturyLink does not. I do now know how to get the GPON password as I was never in that scenario.

    Once you are done, wait for the ONT to boot succesfully, then turn off the power, close the ONT, and plug the fiber and power in place of your stock Calix ONT.

    An example of a JTAG session can be seen here.

  • Setting up Login for Windows Server/Samba Active Directory on FreeBSD

    Recently, in my homelab, I decided to enable a single sign-on using Active Directory on my two servers. Despite my employment, my homelab is very FreeBSD-centric, due to me having used it for 9+ years versus 2+ at my current job.

    While I could use OpenLDAP which is technically more Unix-centered than Windows-centered, I hate OpenLDAP. I find it easier to use Active Directory, whether Windows or Samba, as I am currently using a Samba 4.13 Domain Controller on FreeBSD.

    Going on, you’ll want to set your hostname in the format of SYSTEM_NAME.AD_DOMAIN_NAME. This can be done with:

    sysrc hostname="SYSTEM_NAME.AD_DOMAIN_NAME" 

    The all-caps fields should be self-explanatory.

    You’ll also want a static IP, or an entry for your host in the DNS/DHCP. If you go the static IP route, set one like:

    sysrc ifconfig_INTNAME="inet IP_ADDRESS netmask SUBNET_MASK" 

    Again, the all-caps fields should be self-explanatory.

    If you have a static IP, you need an entry for your system in /etc/hosts like:

    IP_ADDRESS	SYSTEM_NAME.AD_DOMAIN_NAME AD_DOMAIN_NAME 

    You’ll also want to make sure the time is accurate on both the domain controller and system joining the domain.

    Then install Samba and pam_mkhomedir:

    # pkg install samba413 pam_mkhomedir 

    Note: At the time of writing, the latest Samba package is samba413. This could change in the future.

    Then, you’ll want to set up /usr/local/etc/smb4.conf:

    [global]
    	netbios name = SYSTEM_HOSTNAME
    	realm = AD_DOMAIN_NAME
    	workgroup = AD_NETBIOS_NAME
    	security = ADS
    	winbind enum groups = Yes
    	winbind enum users = Yes
    	winbind nss info = rfc2307
    	idmap config *:range = 10000-99999
    	idmap config * : backend = tdb
    	template shell = /bin/sh
    	template homedir = /home/%U

    Like always, the all-caps fields with underscores should be self-explanatory.

    If you don’t have a /home or /usr/home directory, make one now as root:

    # mkdir /home 

    Then, you should test the Samba configuration, just to be safe:

    # testparm 

    Now, join the domain and enter the domain’s “Administrator” password:

    # net ads join -U administrator 

    The AD DC should have the FreeBSD box you are joining registered.

    Now, enable samba_server and winbindd as follows:

    # sysrc samba_server_enable="YES"
    # sysrc winbindd_enable="YES" 

    And start Samba:

    # service samba_server start 

    Just to make sure, check that you can see the AD users and groups:

    # wbinfo -u # wbinfo -g 

    I have tested these instructions on both a Samba 4.13/FreeBSD 13.0 and Windows Server 2022 Active Directory Domain Controller.

    Next, we need to edit /etc/nsswitch.conf. In this file, change these two lines:

    group: files winbind
    passwd: files winbind 

    Now, we edit the PAM configuration. Edit /etc/pam.d/system to look like this:

    auth            sufficient      pam_opie.so             no_warn no_fake_prompts
    auth            requisite       pam_opieaccess.so       no_warn allow_local
    auth            sufficient      /usr/local/lib/pam_winbind.so
    #auth           sufficient      pam_krb5.so             no_warn try_first_pass
    #auth           sufficient      pam_ssh.so              no_warn try_first_pass
    auth            required        pam_unix.so             no_warn try_first_pass nullok
    
    # account
    account         sufficient      /usr/local/lib/pam_winbind.so
    #account        required        pam_krb5.so
    account         required        pam_login_access.so
    account         required        pam_unix.so
    
    # session
    session         required        /usr/local/lib/pam_mkhomedir.so
    #session        optional        pam_ssh.so              want_agent
    session         required        pam_lastlog.so          no_fail
    
    # password
    password        sufficient      /usr/local/lib/pam_winbind.so
    #password       sufficient      pam_krb5.so             no_warn try_first_pass
    password        required        pam_unix.so             no_warn try_first_pass
    

    Then change /etc/pam.d/sshd to look like this:

    auth            sufficient      pam_opie.so             no_warn no_fake_prompts
    auth            requisite       pam_opieaccess.so       no_warn allow_local
    auth            sufficient      /usr/local/lib/pam_winbind.so
    #auth           sufficient      pam_krb5.so             no_warn try_first_pass
    #auth           sufficient      pam_ssh.so              no_warn try_first_pass
    auth            required        pam_unix.so             no_warn try_first_pass
    
    # account
    account         sufficient      /usr/local/lib/pam_winbind.so
    account         required        pam_nologin.so
    #account        required        pam_krb5.so
    account         required        pam_login_access.so
    account         required        pam_unix.so
    
    # session
    session         required        /usr/local/lib/pam_mkhomedir.so
    #session        optional        pam_ssh.so              want_agent
    session         required        pam_permit.so
    
    # password
    password        sufficient      /usr/local/lib/pam_winbind.so
    #password       sufficient      pam_krb5.so             no_warn try_first_pass
    password        required        pam_unix.so             no_warn try_first_pass

    Note: On FreeBSD 14.x or later, remove the pam_opie.so and pam_opieaccess.so lines as they will cause PAM issues.

    You can also add these to other /etc/pam.d files if you desire AD login support from other parts of the system (e.g. X11, VPN, etc.).

    Reboot, and you should be set.

    If you desire additional security, you could:

    • In sshd, add the AllowGroups AD_DOMAIN_NAME\GROUP_NAME to the sshd_config
    • If you wish for some users to have root access, add %AD_DOMAIN_NAME\\GROUP_NAME ALL=(ALL) NOPASSWD: ALL to the sudoers file (note the double slash)

    Source: FreeBSD: Setup Samba as an AD Domain Member

  • Optimizing FreeBSD Power Consumption on Modern Intel Laptops

    My current FreeBSD laptop is a 2020 14″ HP Spectre x360, which uses Intel’s 11th Gen CPU and “Evo” platform, although I previously also had the 13″ 2020 version with a similar setup (but lacked working audio on non-Windows). This article isn’t specific to HP: your shiny-new Lenovo ThinkPad, Dell XPS, or Framework Laptop can also apply.

    One thing with FreeBSD is that unlike Windows or desktop Linux, the default configuration is poorly optimized for laptops that are newer than your ancient ThinkPad T420, or maybe a T460s.

    Having run FreeBSD on TigerLake on-and-off since December 2020 on two laptops, there are a few things to keep in mind. These are:

    On TigerLake, go CURRENT for graphics (As of March 2022)

    UPDATE: This section is obsolete, as of April 2022 13.1-RC2 works with drm-kmod from GitHub if you use the 5.9 branch.

    If you want accelerated graphics, as of March 2022, you need to run 14-CURRENT branch, or maybe 13-STABLE (which I haven’t tested).

    For graphics, while drm-kmod from Ports “works”, at the time of writing the best performance and stability comes with the GitHub master branch of drm-kmod which as of writing is at Linux 5.8.

    When 14.0-RELEASE comes out, it should work fine for TigerLake, maybe even 13.1 (although I personally reserve RELEASE versions for non-desktops). For Intel CannonLake (10th Gen) or older, 13.0-RELEASE or newer should be fine. For AlderLake (12th Gen) and newer, I don’t know if 14.0-RELEASE will be supported or not by drm-kmod.

    Power consumption

    A big problem with newer Intel CPUs is that the fan is constantly running by default, and these laptops gets real hot. It’s not just Intel TigerLake, but also Intel WhiskeyLake (8th Gen Refresh) on an older 2018 13″ HP Spectre x360 (which presently is my secondary laptop).

    Some of the issues is FreeBSD’s default Intel Speed Shift (ISS) configuration which makes more sense for desktops and servers (or anything lacking a battery) than laptops.

    By default, ISS optimizes the clock for the whole CPU (all cores) than each core individually. To fix that, you can include this in /boot/loader.conf:

    machdep.hwpstate_pkg_ctrl=0 

    Which will make the ISS control core-based, so if one core is busy your fan won’t be as loud.

    You can also optimize ISS for maximum power savings, as opposed to “balanced”, which helps improve battery life even more. If you do this, you need this in your /etc/sysctl.conf:

    dev.hwpstate_intel.0.epp=100 dev.hwpstate_intel.1.epp=100 dev.hwpstate_intel.2.epp=100 ... dev.hwpstate_intel.N.epp=100 

    Where N is the number of cores.

    The values of this is that:

    • 0 is “maximum performance”
    • 50 is a “balance” (default)
    • 100 is “maximum power savings”

    I keep dev.hwpstate_intel.* at 100 which I recommend for a laptop, but it’s optional.

    CURRENT notes

    If you run RELEASE or STABLE feel free to skip this section.

    However, If you run CURRENT as a desktop like me, power consumption can be improved by running the GENERIC-NODEBUG kernel and disabling debugging symbols in userland. This is a good idea provided you aren’t planning to do kernel hacking on your laptop (or do it in a VM).

    To disable debugging symbols for the kernel and userland, include this in /etc/src.conf:

    KERNCONF="GENERIC-NODEBUG"
    WITH_MALLOC_PRODUCTION="YES"
    WITHOUT_LLVM_ASSERTIONS="YES" 

    Source: an old Twitter thread originated by yours truly.

    While not specific to new Intel CPUs, enabling “metadata” mode on src builds can quicken updates. You can find the information on FreeBSD’s wiki.

    Results

    Even though I can’t always stop the fan from running, I can stop it from running loud most of the time. On a stock FreeBSD, doing about anything meant a loud fan. With FreeBSD tuned according to this document, it’s quiet as a mouse. Well, almost: the fan still runs, and that’s normal, but when it does, it’s much quieter.

  • FreeBSD (or pfSense/OPNsense) on the HP t740 Thin Client

    While expensive and hard to find on eBay (thanks, ServeTheHome), the HP t740 “Thin Client” is a great pfSense box if you want more power, or a compact home server.

    While I could get away with a t730 or t620 Plus, but I have CenturyLink Fiber and PPPoE is more computationally intensive versus pure DHCP. That running a Tor relay, so I’d like some headroom and upgrade path to 10 Gigabits. [1].

    PS/2 Freezes

    While the t740 is a neat box, if you plan to run FreeBSD or its derivatives like pfSense, OPNsense, or HardenedBSD on the bare metal (as opposed to inside ESXi or Proxmox), an out of the box configuration freezes at boot on:

    atkbd0: [GIANT-LOCKED] 

    To solve the issue, at the boot prompt, hit ESC, and the enter:

    unset hint.uart.0.at unset hint.uart.1.at 

    Note: You need to unset both, otherwise it will lock up at boot.

    After you install, but before rebooting, open a post-installation shell, and run:

    vi /boot/loader.conf.local 

    Add these two lines:

    hint.uart.0.disabled="1" hint.uart.1.disabled="1" 

    This will fix the issue across reboots and firmware upgrades on pfSense/OPNsense. Thanks, Ed Gonzales for reporting my old “solution” didn’t work across firmware upgrades. That explained why my OPNsense box suddenly stopped working after an upgrade (New section, Septemper 11, 2022).

    I have run pfSense CE 2.5.2 and am currently running OPNsense 22.1 on my t740 without issues after doing the steps above.

    SSD

    If you are using the HP M.2 eMMC, it is not detected on an out-of-the-box FreeBSD installation. In that case, you will need a third-party M.2 SSD. I’m using a Samsung 970 EVO 250GB [2], but any M.2 can do, SATA or NVMe.

    [1] – Plus after cloning my ONT, I got rid of the connection limit issue.

    [2] – I normally buy off-brand “budget” SSDs (don’t ask me why), but Best Buy shipped faster than Amazon when I needed the SSD. The 970 EVO is what was in stock.

  • Tuning Power Consumption on FreeBSD Laptops and Intel Speed Shift (6th Gen and Later)

    When running FreeBSD on laptops with a 6th Gen (Skylake) or later Intel CPU, for me these are HP Spectre x360s (sorry, I’m not a ThinkPad fan), one annoyance with the out of the box FreeBSD configuration is the fact that the fan is running most of the time.

    In comparison, a HP Envy with an AMD Ryzen does not have this issue with an out-of-the-box FreeBSD.

    One thing that Intel has done with these modern CPUs is include a technology called Speed Shift. While Windows and Linux may have configurations that automatically optimize for computers with batteries or without, FreeBSD’s default Speed Shift configuration is more optimized for computers without a battery. Meaning it attempts a “balance” between “performance” and “power consumption”, but this also means the Spectre’s fan is always running.

    Fortunately, this can be tuned, as per the hwpstate_intel man page.

    In short, what you need is this in your /etc/sysctl.conf:

    dev.hwpstate_intel.0.epp=100 dev.hwpstate_intel.1.epp=100 ... dev.hwpstate_intel.N.epp=100 

    Where N is the number of threads minus one.

    In case you were wondering, the 100 is actually a value between 0 (best performance) or 100 (most power savings). The default is 50 which attempts a balance, but I set it to 100 for laptops.

    For me, I have a 4-core, 8-thread Intel Core i7-1165G7 in my Spectre x360 14", and the respective /etc/sysctl.conf entry is:

    dev.hwpstate_intel.0.epp=100 dev.hwpstate_intel.1.epp=100 dev.hwpstate_intel.2.epp=100 dev.hwpstate_intel.3.epp=100 dev.hwpstate_intel.4.epp=100 dev.hwpstate_intel.5.epp=100 dev.hwpstate_intel.6.epp=100 dev.hwpstate_intel.7.epp=100 

    You can either “reboot” (easier for me), or do sysctl dev.hwpstate_intel.0-N.epp=100 manually if you want it done right away.

    And enjoy the fan not running all the time! The fan will still run, but less frequently than it did earlier.

  • Setting up a Signal Proxy using FreeBSD

    With the events that the private messaging app Signal has been blocked in Iran, Signal has come up with an “proxy” solution akin to Tor’s Bridges, and have given instructions on how to do it.

    For people who prefer FreeBSD over Linux like myself, we obviously can’t run Docker, which is what Signal’s instructions focus on.

    Fortunately, the Docker image is just a fancy wrapper around nginx, and the configs can be ported to any OS. Here, I’ll show you how to set up a Signal Proxy on FreeBSD.

    Prerequisites

    You will need a FreeBSD server that is not running anything on Port 80 or 443. If you don’t run FreeBSD, you can substitute the commands with ones specific to your OS or Linux distro.

    You can also substitute acme.sh with another ACME-compatible Let’s Encrypt client, or use another CA. I used acme.sh with ZeroSSL, but won’t describe the latter here for simplicity’s sake.

    Steps

    First, you’ll need to install acme.sh and nginx:

    pkg install acme.sh nginx 

    Then, you’ll need to get an SSL certificate:

    acme.sh --register-account -m neel@neelc.org --server zerossl
    acme.sh --issue --standalone -d DOMAIN 

    Replace DOMAIN with the hostname you want to use.

    Next, use the following config for /usr/local/etc/nginx/nginx.conf:

    load_module /usr/local/libexec/nginx/ngx_stream_module.so;
    user www;
    
    events {}
    
    stream {
        map $ssl_preread_server_name $name {
            textsecure-service.whispersystems.org    signal-service;
            storage.signal.org                       storage-service;
            cdn.signal.org                           signal-cdn;
            cdn2.signal.org                          signal-cdn2;
            api.directory.signal.org                 directory;
            contentproxy.signal.org                  content-proxy;
            uptime.signal.org                        uptime;
            api.backup.signal.org                    backup;
            sfu.voip.signal.org                      sfu;
            updates.signal.org                       updates;
            updates2.signal.org                      updates2;
            default                                  deny;
        }
    
        upstream relay {
             server localhost:4433;
        }
    
        upstream signal-service {
             server textsecure-service.whispersystems.org:443;
        }
    
        upstream storage-service {
            server storage.signal.org:443;
        }
    
        upstream signal-cdn {
            server cdn.signal.org:443;
        }
    
        upstream signal-cdn2 {
            server cdn2.signal.org:443;
        }
    
        upstream directory {
            server api.directory.signal.org:443;
        }
    
        upstream content-proxy {
            server contentproxy.signal.org:443;
        }
    
        upstream backup {
            server api.backup.signal.org:443;
        }
    
        upstream sfu {
            server sfu.voip.signal.org:443;
        }
    
        upstream updates {
            server updates.signal.org:443;
        }
    
        upstream updates2 {
            server updates2.signal.org:443;
        }
    
        upstream deny {
            server 127.0.0.1:9;
        }
    
        server {
            listen                443 ssl;
            proxy_pass            relay;
    
            access_log            off;
            error_log             /dev/null;
    
            ssl_certificate     /root/.acme.sh/DOMAIN/fullchain.cer;
            ssl_certificate_key /root/.acme.sh/DOMAIN/DOMAIN.key;
         }
    
        server {
            listen                4433;
            proxy_pass            $name;
            ssl_preread           on;
            error_log             /dev/null;
            access_log            off;
         }
    }

    Again replace DOMAIN with the domain your Signal proxy is on.

    After you have set the nginx config, enable it via sysrc:

    sysrc nginx_enable=YES 

    And start it:

    service nginx start 

    You should have a fully-functioning Signal proxy.

    Share the proxy

    While the official Signal instructions are very Docker-centric for the tech part, it does have other useful information on sharing the proxy securely. This means I won’t duplicate the information here.

    Here’s the subsection on Signal’s website on sharing the proxy.