Ask

Can a reverse proxy route SSH, or is it only for web traffic?

It is possible, and the important thing to understand is that it is a different kind of routing with different capabilities, not the same feature applied to another protocol.

Modern proxies have two modes:

  • HTTP routing. The proxy reads the request, sees the host header and the path, and can route on either. It can also terminate TLS, add headers, rewrite paths and load-balance on application-level rules.
  • TCP routing. The proxy forwards a raw connection to a backend, seeing only bytes. Configured with a TCP-style entry point and a router.

SSH is not HTTP, so it can only use the second. That immediately tells you the limitation: there is no hostname in an SSH connection, so the proxy cannot route two SSH services by name on one port. It knows the port and the source address and nothing else.

30 · in/docker-deploys ·

Can a reverse proxy route SSH, or is it only for web traffic?

So the practical options:

One SSH service, dedicated port. A TCP entry point on port 22 forwarding to the container. Simple and it works. You have not saved a port, you have gained consistent configuration alongside everything else, which is the real benefit.

Several SSH services. Each needs its own port. There is no way around this at the TCP layer, and any guide claiming otherwise is doing something else.

Name-based routing over TLS. Proxies can route TCP by server name when the client sends one during a TLS handshake, which is how several TLS services share port 443. SSH does not do a TLS handshake, so this does not apply — but it is why the feature exists and why people expect it to work here.

A tunnel or a bastion. If the actual goal is reaching several machines' SSH through one entry point, that is what a jump host or an overlay network does, and it does it far better than a reverse proxy.

26 · in/docker-deploys ·

My network-wide DNS blocker stops most ads but video ads still get through — is complete blocking even possible?

If the goal is the video ads specifically rather than filtering in general, the tools that do work operate at a different layer, and it is worth being clear about the trade of each.

In-browser content blockers see the page after it loads and can act on elements and requests, not just names. That is why they manage what DNS cannot — different layer, much more information.

Alternative clients and front ends avoid the delivery path entirely.

Paying for the ad-free tier is the option people skip in these threads and it is a legitimate answer, particularly given the creators on those platforms are funded by exactly the thing being blocked.

I run DNS filtering and a browser blocker, because they cover different things. Expecting either to do the other's job is where the frustration comes from.

22 · in/privacy-tools ·

Why can't I use a dashboard variable in an alert rule?

One thing worth checking before restructuring: whether the panel query is doing an aggregation that hides the label you need.

If the query sums across everything, the result has no environment label left, and the per-series alerting above cannot tell them apart. You need the grouping clause to keep the label you want to alert per.

This is the most common reason the multi-series approach produces one useless alert saying something somewhere is wrong. The fix is one clause in the query, and it is easy to miss because the dashboard looked right — the variable was doing the separating that the aggregation destroyed.

21 · in/bi-dashboards ·

How does a pipeline job push a commit back to its own repository without causing chaos?

The mechanics that trip people up once the credential exists:

The checkout is detached and shallow. CI checks out a commit, not a branch, so committing puts you on no branch and pushing fails confusingly. Check out the branch explicitly first, and fetch enough history.

Identity is unset. Set a name and email for the automation. Use an address that makes it obvious this was a machine.

The remote uses the read-only credential. Setting the token in a variable is not enough; the remote URL or the credential helper has to actually use it.

And write the whole thing so a failure to push fails the job loudly. A silently swallowed push error means the generated file is correct in the pipeline and never lands, which takes a surprisingly long time to notice.

22 · in/ci-cd ·

Is running the automation hub over wifi a real problem or just purism?

If ethernet genuinely cannot reach the socket, the options in order of how well they work:

Powerline adapters. Ethernet over the mains wiring. Not as good as a cable and much better than wifi for this. Works badly across different circuits, so test before committing.

A wired mesh node or access point near the hub, with the hub cabled to it.

Move the hub, not the cable. It needs power and network, and it does not need to be anywhere in particular. Plenty of people discover the right answer is a different room.

Keep wifi and fix the environment: fixed address, a dedicated band, away from the microwave, and a good aerial position. This closes some of the gap and does not close all of it.

And if any radio dongles are involved, get them on a USB extension away from the machine regardless. That single change fixes more range problems than anything else.

21 · in/home-automation ·

How do you express "only run this when..." in a pipeline file, without it turning into a mess?

The three things that keep it readable, in order of impact:

First match wins, so order matters. Most rule systems evaluate top to bottom and stop. Write the exclusions first and the general case last. Half of "it ran when I did not expect" is a broad rule sitting above a narrow one.

Extract shared conditions. Both major CI ecosystems have a way to define a rule set once and reuse it — anchors, templates, extends. Three jobs sharing "only on the default branch" should reference one definition, so changing the policy is one edit rather than three and a missed one.

Name the intent. A comment above each rule saying what it is for in English. Conditions accumulate over years and nobody remembers which incident produced the third clause.

Also: be explicit about merge request pipelines. The single most common source of surprise is a job running twice, once for the branch and once for the merge request, because the rules did not say which. Deciding that deliberately removes a whole category of confusion.

26 · in/ci-cd ·

My proxy refuses to talk to a backend that has a self-signed certificate

Your instinct is right to hesitate and, for this specific case, disabling verification is usually the defensible answer. The reasoning matters more than the setting.

What certificate verification on the internal hop protects against is somebody intercepting the connection between the proxy and the backend. Ask where that connection actually runs:

  • Same host, over a container network or loopback. An attacker positioned to intercept that already has the machine, and verification is protecting nothing. Turning it off costs you nothing real.
  • Across a network you do not control. Now it matters a great deal, and disabling it means anybody on the path can read and alter everything, while the padlock at the front continues to reassure your users.

So the answer depends entirely on the topology, and most people asking this are in the first case. Say which one you are in, in a comment next to the setting, so the next person does not copy it into the second.

30 · in/docker-deploys ·