Block incoming connections with hostnames that contain IP addresses - postfix-mta

I used to run qmail with spamdyke, and spamdyke has a nifty ability to block incoming mail if the host looks like these:
static-68-179-34-50.ptr.terago.net
c-75-74-22-18.hsd1.fl.comcast.net
173-14-159-121-newengland.hfc.comcastbusiness.net
rrcs-24-43-130-226.west.biz.rr.com
va-65-40-217-136.sta.embarqhsd.net
unused-66-33-224-181.unused.epix.net
c-67-190-66-10.hsd1.co.comcast.net
Basically, it had some form of the IP addres in the hostname, which usually designates dynamic clients, et cetera.
Since they have no reason to try to send mail directly to my SMTP server, they can be considered spammers with 99.99% certainty.
What is the easiest way to achieve same functionality with postfix?
http://www.spamdyke.org/documentation/README.html#RDNS

Usually its safer to use the spamhaus PBL, but you can do this with
smtpd_helo_restrictions = reject_invalid_hostname, check_helo_access regexp:/etc/postfix/helo.regexp
in the helo.regexp add
/[0-9]+-[0-9]+-[0-9]+-[0-9]+[.-#]/ REJECT
You can fine tune it if you want, or use PCRE instead (dont forget to update the format in the smtpd_helo_restrictions line)

Related

Remap only the scheme part of URIs

The mosquitto MQTT client builds URIs of the form mqtt://host:port or mqtts://host:port without an option to override the scheme part. The broker, however, accepts MQTT connections only under tcp://host:port or ssl://host:port. Is there a way to proxy mqtt:// to tcp:// and mqtts:// to ssl://?
There is no need to make any change.
The client library interprets the scheme section internally, it is not presented to the broker in any form.
You just need to pick the right one for the version of the client you are using.

Is it possible to build an arp request packet in such a way that will cause a router to forward it over subnets?

What I'm trying to do is get all the ip addresses in my network, and I thought, assuming I know the address of all subnets could use arp requests to achieve that if there was a way to forward these requests over different subnets.
For example , assume I had two hosts
192.168.0.2/24 and 192.168.1.2/24
connected via router using IP addresses 192.168.0.1/16 192.168.1.1/16.
I would like to send an arp request from 192.168.0.2/16 to 192.168.1.2/16.
I thought maybe if the arp request was encapsulated in layer 3 header containing 192.168.1.2/24, or 192.168.1.255/24 as the dsetination this will work.
If it is possible and you know a tool that does that I will be happy to know about this tool.
If it isn't, I would like to know what happens to a packet like the one I described above
I would like to know what happens to a packet like the one I described above
If you encapsulate some info into standard IP-packet, then, naturally, it will be routed to the IP-destination host. Yet if the remote host knew nothing about this non-standard packet, then nothing would happen.
If you really want to get something out of this, you need to have up and running some software server on that remote host, which is able to process your requests. That is, you need some Proxy ARP: either existing implementation, or made of your own.
If you don't have such "an agent" in the target subnetwork, then you're out of luck. Go with sequential IP-scanning until be banned by admin.

How can I proof my IP address?

If I connect directly to another computer, I proof my IP. But what if I want to receive a message on paper which proofs someones IP?
For example, client contacts Google for an JSON web signature, prints it out on paper, gives the paper to me, and I can verify the signature of the message containing their IP, without ever connecting over to the client (or to Google) by TCP.
Is there a simpeler or better scheme possible?
If you use encryption, consider using HMAC. If not, then a simple hash or random number is fine for trivial use, as long as it is unique for a given period of time and then expires. Either way, you can send the generated value across both transports so they can be matched to each other. Preferably the server should generate the value to ensure its authenticity, eg:
"Hello TCP client, send me XXX and your IP over the other transport".
"Hello transport client, I see you sent me value XXX and IP YYY, I have a matching TCP client".
Also keep in mind that if your TCP client is behind a router, the other party is going to see your router's public IP, not your client's private IP behind the router. So your client will have to send the router's IP, and maybe also send its private IP as well. Depends on your actual needs.
I don't really see the need to validate the IP, though. Just dealing with the router situation, let alone trying to avoid IP spoofing, makes it almost not worth doing. Just having an authenticated token should be good enough.
Update: If that is not what you want, then you have to include the IP as part of the encryption/hash. The client takes some seed values (sometimes known as nonce values) and its IP and hashes them all together, then the result is given to the other party. That party uses the same seed/nonce values and the IP it wants to validate and hashes them together and sees if it comes up with the same result. If so, the IPs match.

The reason for a mandatory 'Host' clause in HTTP 1.1 GET

Last week I started quite a fuss in my Computer Networks class over the need for a mandatory Host clause in the header of HTTP 1.1 GET messages.
The reason I'm provided with, be it written on the Web or shouted at me by my classmates, is always the same: the need to support virtual hosting. However, and I'll try to be as clear as possible, this does not appear to make sense.
I understand that in order to allow two domains to be hosted in a single machine (and by consequence, share the same IP address), there has to exist a way of differentiating both domain names.
What I don't understand is why it isn't possible to achieve this without a Host clause (HTTP 1.0 style) by using an absolute URL (e.g. GET http://www.example.org/index.html) instead of a relative one (e.g. GET /index.html).
When the HTTP message got to the server, it (the server) would redirect the message to the appropriate host, not by looking at the Host clause but, instead, by looking at the hostname in the URL present in the message's request line.
I would be very grateful if any of you hardcore hackers could help me understand what exactly am I missing here.
This was discussed in this thread:
modest suggestions for HTTP/2.0 with their rationale.
Add a header to the client request that indicates the hostname and
port of the URL which the client is accessing.
Rationale: One of the most requested features from commercial server
maintainers is the ability to run a single server on a single port
and have it respond with different top level pages depending on the
hostname in the URL.
Making an absolute request URI required (because there's no way for the client to know on beforehand whether the server homes one or more sites) was suggested:
Re the first proposal, to incorporate the hostname somewhere. This
would be cleanest put into the URL itself :-
GET http://hostname/fred http/2.0
This is the syntax for proxy redirects.
To which this argument was made:
Since there will be a mix of clients, some supporting host name reporting
and some not, it just doesn't matter how this info gets to the server.
Since it doesn't matter, the easier to implement solution is a new HTTP
request header field. It allows all clients and servers to operate as they
do now with NO code changes. Clients and servers that actually need host
name information can have tiny mods made to send the extra header field
containing the URL and process it.
[...]
All I'm suggesting is that there is a better way to
implement the delivery of host name info to the server that doesn't involve
hacking the request syntax and can be backwards compatible with ALL clients
and servers.
Feel free to read on to discover the final decision yourself. But be warned, it's easy to get lost in there.
The reason for adding support for specifying a host in an HTTP request was the limited supply of IP addresses (which was not an issue yet when HTTP 1.0 came out).
If your question is "why specify the host in a Host header as opposed to on the Request-Line", the answer is the need for interopability between HTTP/1.0 and 1.1.
If the question is "why is the Host header mandatory", this has to do with the desire to speed up the transition away from assigned IP addresses.
Here's some background on the Internet address conservation with respect to HTTP/1.1.
The reason for the 'Host' header is to make explicit which host this request refers to. Without 'Host', the server must know ahead of time that it is supposed to route 'http://joesdogs.com/' to Joe's Dogs while it is supposed to route 'http://joscats.com/' to Jo's Cats even though they are on the same webserver. (What if a server has 2 names, like 'joscats.com' and 'joescats.com' that should refer to the same website?)
Having an explicit 'Host' header make these kinds of decisions much easier to program.

Determining when to try an IPv6 connection and when to use IPv4

I'm working on a network client program that connects to public servers, specified by the user. If the user gives me a hostname to connect to that has both IPv4 and IPv6 addresses (commonly, a DNS name with both A and AAAA records), I'm not sure how I should decide which address I should connect to.
The problem is that it's quite common for machines to support both IPv4 and IPv6, but only to have global connectivity over IPv4. The most common case of this is when only IPv6 link-local addresses are configured. At the moment the best alternatives I can come up with are:
Try the IPv6 address(es) first - if the connection fails, try the IPv4 address(es); or
Just let the user specify it as a config setting ("prefer_ipv6" versus "prefer_ipv4").
The problem I can see with option 1 is that the connection might not fail straight away - it might take quite a while to time out.
Please do try IPv6. In the significant majority of installations, trying to create an IPv6 connection will fail right away if it can't succeed for some reason:
if the system doesn't support IPv6 sockets, creating the socket will fail
if the system does support IPv6, and has link-local addresses configured, there won't be any routing table entry for the global IPv6 addresses. Again, the local kernel will report failure without sending any packets.
if the system does have a global IP address, but some link necessary for routing is missing, the source should be getting an ICMPv6 error message, indicating that the destination cannot be reached; likewise if the destination has an IPv6 address, but the service isn't listening on it.
There are of course cases where things can break, e.g. if a global (or tunnel) address is configured, and something falsely filters out ICMPv6 error messages. You shouldn't worry about this case - it may be just as well that IPv4 connectivity is somehow broken.
Of course, it's debatable whether you really need to try the IPv6 addresses first - you might just as well try them second. In general, you should try addresses in the order in which they are returned from getaddrinfo. Today, systems support configuration options that let administators decide in what order addresses should be returned from getaddrinfo.
Subsequent to the question being asked the IETF has proposed an answer to this question with RFC6555, a.k.a. Happy Eyeballs.
The pertinent point being the client and server may both have IPv4 and IPv6 but a hop in between may not so it is impossible to reliably predict which path will work.
You should let the system-wide configuration decide thanks to getaddrinfo(). Just like Java does. Asking every single application to try to cater for every single possible IPv6 (mis)configuration is really not scalable! In case of a misconfiguration it is much more intuitive to the user if all or none applications break.
On the other hand you want to try to log annoying delays and time-outs profusely, so users can quickly identify what to blame. Just like every other delays ideally, including (very common) DNS time-outs.
This talk has the solution. To summarize;
Sometimes there are problems with either DNS lookups or the subsequent connection to the resolved address
You don't want to wait for connecting to an IPv6 address to timeout before connecting to the IPv4 address, or vice versa
You don't want to wait for a lookup for an AAAA record to timeout before looking for an A record or vice versa
You don't want to stall while waiting for both AAAA and A records before attempting to connect with whichever record you get back first.
The solution is to lookup AAAA and A records simultaneously and independently, and to connect independently to the resolved addresses. Use whatever connection succeeds first.
The easiest way to do this is to allow the networking API do it for you using connect-by-name networking APIs. For example, in Java:
InetSocketAddress socketAddress = new InetSocketAddress("www.example.com", 80);
SocketChannel channel = SocketChannel.open(socketAddress);
channel.write(buffer);
The slide notes say at this point:
Here we make an opaque object called an InetSocketAddress from a host
and port, and then when we open that SocketChannel, that can complete
under the covers, doing whatever is necessary, without the
application ever seeing an IP address.
Windows also has connect-by-name APIs. I don’t have code fragments for
those here.
Now, I’m not saying that all implementations of these APIs necessarily
do the right thing today, but if applications are using these APIs,
then the implementations can be improved over time.
The di!erence with getaddrinfo() and similar APIs is that they
fundamentally can’t be improved over time. The API definition is that
they return you a full list of addresses, so they have to wait until
they have that full list to give you. There’s no way getaddrinfo can
return you a partial list and then later give you some more.
Some ideas:
Allow the user to specify the preference on a per-site basis.
Try IPv4 first.
Attempt IPv6 in parallel upon the first connection.
On subsequent connections, use IPv6 if the connection was successful previously.
I say to try IPv4 first because that is the protocol which is better established and tested.

Resources