<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="atom-style.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <id>https://corion.net/blog/tag/blogpost/</id>
    <title>Corions Musings</title>
    <updated>2026-05-17T00:00:00Z</updated>
    <link href="https://corion.net/blog/tag/blogpost.atom" rel="self" />
    <link href="https://corion.net/blog/tag/blogpost/" rel="alternate" />
    <generator version="0.098">Statocles</generator>

    <entry>
        <id>https://corion.net/blog/2026/05/17/override-firefox-lwp-useragent-and-curl-dns-resolution/</id>
        <title>Override Firefox, LWP::UserAgent and curl DNS resolution</title>
        <link href="https://corion.net/blog/2026/05/17/override-firefox-lwp-useragent-and-curl-dns-resolution/" rel="alternate" />
        <content type="html"><![CDATA[
            <p>This post is part of the notes I took while preparing for and during the migration of <a href="https://perlmonks.org">https://perlmonks.org</a> behind a CDN. I mostly publish these notes so that I can find them again later.</p>

<p>There are situations where I don&#39;t want to override the DNS resolution for my complete system, but still connect to specific machines pretending a DNS name resolves to them. Examples are SSL certificate checking, and various firewall configurations. Especially while migrating a site behind a CDN or when setting up s site beh[nd a reverse proxy or Wireguard, I want to inspect and compare the results of queries to the different machines.</p>

<p>For these examples, assume that <code>10.0.0.1</code> is the machine serving the website
<code>perlmonks.org</code> as the origin. The public DNS resolves to a pool of CDN machines
somewhere else, but we want to debug what the original source is serving.
The original machine also wants to be accessed as <code>perlmonks.org</code> over SSL.</p>

<h2>Override <code>curl</code> name resolution</h2>

<p>This is documented in the <a href="https://curl.se/docs/manpage.html#--resolve">curl manpage</a></p>

<pre><code>curl --resolve perlmonks.org:443:10.0.0.1 https://...
</code></pre>

<h2>Override Firefox name resolution</h2>

<p>Open the Firefox browser console with <code>Ctrl+Shift+J</code> . You should be able to enter Javascript there; If not, enable &quot;Debugging Tools für Browser-Chrome&quot; in the normal browser console settings (<code>F12</code> , then <code>F1</code> <em>yeah, CUI standards be damned</em> ). Then enter the name/IP pair for name resolution. This persists until you restart Firefox.</p>

<pre><code>const gOverride = Cc[&quot;@mozilla.org/network/native-dns-override;1&quot;].getService(Ci.nsINativeDNSResolverOverride);
gOverride.addIPOverride(&quot;perlmonks.org&quot;, &quot;10.0.0.1&quot;);
</code></pre>

<h1>Override LWP::UserAgent DNS name resolution</h1>

<p>For LWP::UserAgent there is no general mechanism, but monkeypatching <code>LWP::Protocol::https</code> works. To also make SNI work, you
should additionally pass in the <code>SSL_hostname</code> explicitly to the SSL options. I&#39;m not sure why this is necessary, as the code in <a href="https://metacpan.org/dist/LWP-Protocol-https/source/lib/LWP/Protocol/https.pm"><code>LWP::Protocol::https</code></a>
extracts the hostname from the request URL, but this made the difference for me between <code>421 Misdirected Request</code> and <code>200 OK</code> with Fastly :</p>

<pre><code>our $force_peeraddr;
around &#39;LWP::Protocol::http::_extra_sock_opts&#39; =&gt; sub {
        my $orig = shift;
        die unless wantarray;
        my @rv = $orig-&gt;(@_);
        push @rv, PeerAddr =&gt; $force_peeraddr if defined $force_peeraddr;
        return @rv;
};
around &#39;LWP::Protocol::https::_get_sock_info&#39; =&gt; sub {
        my $orig = shift;
        my ($self, $res, $sock) = @_;
        my $cert = $sock-&gt;get_peer_certificate;
        my @san = $cert-&gt;peer_certificate(&#39;subjectAltNames&#39;);
        use Data::Dumper; warn Dumper \@san;
        while (@san) {
                my ($type_id, $value) = splice @san, 0, 2;
                $res-&gt;push_header(&quot;Client-SSL-Cert-SubjectAltName&quot;
                        =&gt; &quot;$type_id: $value&quot;);
        }
        $orig-&gt;(@_);
};

$force_peeraddr = &#39;10.0.0.1&#39;;

my $ua = LWP::UserAgent-&gt;new(
    ssl_opts =&gt; {
        verify_hostname =&gt; 0,
        SSL_hostname =&gt; &#39;perlmonks.org&#39;, # for SNI
    },
    timeout =&gt; 60,
);
</code></pre>

<h2>Override Chrome name resolution</h2>

<p>It seems that this is not possible.</p>

<h1>Override <code>wget</code> name resolution</h1>

<p>It seems that this is not possible.</p>


                <p>Tags:
                    <a href="https://corion.net/blog/tag/blogpost/">Blogpost</a>
                    <a href="https://corion.net/blog/tag/programming/">programming</a>
                    <a href="https://corion.net/blog/tag/networking/">networking</a>
                    <a href="https://corion.net/blog/tag/perl/">Perl</a>
                </p>

        ]]></content>
        <updated>2026-05-17T00:00:00Z</updated>
        <category term="Blogpost" />
        <category term="programming" />
        <category term="networking" />
        <category term="Perl" />
    </entry>
</feed>

