Postfix Whitelist for RBL - postfix-mta

Googles outgoing Servers are today listen on SORBS
NOQUEUE: reject: RCPT from mail-ot0-f180.google.com[74.125.82.180]: 451 4.7.1 Service unavailable; Client host [74.125.82.180] blocked using dnsbl.sorbs.net; Currently Sending Spam See: http://www.sorbs.net/lookup.shtml?74.125.82.180;
now I want to whitelist them. But this is not working:
whitelist_recipient:
/^mail-.*\.google\.com$/ OK
Postfix config:
main.cf:
smtpd_recipient_restrictions =
....
check_recipient_access hash:/etc/postfix/whitelist_recipient,
....
reject_rbl_client dnsbl.sorbs.net,
....
But why? postmap whitelist_recipient I had do.
And a
postmap -q "mail-ot0-f180.google.com" regexp:whitelist_recipient
Says: OK
What do I wrong?
Thank you for any help!

Ok, after a lot of time, I found my mistake!
main.cf:
smtpd_recipient_restrictions =
....
check_client_access regexp:/etc/postfix/whitelist_recipient,
....
reject_rbl_client dnsbl.sorbs.net,
....
It not hash: it must regexp:

Related

Nginx - how to access Client Certificate's Subject Alternative Name (SAN) field

I have an Nginx server which clients make requests to with a Client certificate containing a specific CN and SAN. I want to be able to extract the CN (Common Name) and SAN (Subject Alternative Names) fields of that client cert.
rough example config:
server {
listen 443 ssl;
ssl_client_certificate /etc/nginx/certs/client.crt;
ssl_verify_client on; #400 if request without valid cert
location / {
root /usr/share/nginx/html;
}
location /auth_test {
# do something with the CN and SAN.
# tried these embedded vars so far, to no avail
return 200 "
$ssl_client_s_dn
$ssl_server_name
$ssl_client_escaped_cert
$ssl_client_cert
$ssl_client_raw_cert";
}
}
Using the embedded variables exposed as part of the ngx_http_ssl_module module I can access the DN (Distinguished Name) and therefore CN etc but I don't seem to be able to get access to the SAN.
Is there some embedded var / other module / general Nginx foo I'm missing? I can access the raw cert, so is it possible to decode that manually and extract it?
I'd really rather do this at the Nginx layer as opposed to passing the cert down to the application layer and doing it there.
Any help much appreciated.
You can extract them with the Nginx-builtin map, e.g. for CN:
map $ssl_client_s_dn $ssl_client_s_dn_cn {
default "";
~,CN=(?<CN>[^,]+) $CN;
}
I'm not a lua expert, but here's what I got working:
local openssl = require('openssl')
dnsNames = {}
for k,v in pairs(openssl.x509.read(ngx.var.ssl_client_raw_cert):extensions()) do
for k1,v1 in pairs(v:info()) do
if(type(v1)=='table') then
for k2,v2 in pairs(v1) do
if(type(v2)=='table') then
for k3,v3 in pairs(v2) do
if(k3=='dNSName') then
table.insert(dnsNames, v3:toprint())
end
end
end
end
end
end
end
ngx.say(table.concat(dnsNames, ':'))
You can do it through OpenResty + Lua-OpenSSL and parse the raw certificate to get it.
Refer this: https://github.com/Seb35/nginx-ssl-variables/blob/master/COMPATIBILITY.md#ssl_client_s_dn_x509
Just like this:
local varibleName = string.match(require("openssl").x509.read(ngx.var.ssl_client_raw_cert):issuer():oneline(),"/C=([^/]+)")
Had the same problem, when I try to retrieve "subject DN" by a upstream server.
Someone might find the following advice useful. Thus, there is an access
to such fields as ("subject DN" an so on) - you have to look at link1. Beside it, I had to through this data into the request header, so I've done it via 'proxy_set_header' (link2). It was possible without any extra Nginx extension (there is not need to rebuild them with --modules, just default modules)
This is an example how an URI value can be extracted from client certificate extensions and then forwarded to the upstream server as a header. This is useful when implementing WebID over TLS authentication, for example.
location / {
proxy_pass http://upstream;
set_by_lua_block $webid_uri {
local openssl = require('openssl')
webIDs = {}
for k,v in pairs(openssl.x509.read(ngx.var.ssl_client_raw_cert):extensions()) do
for k1,v1 in pairs(v:info()) do
if(type(v1)=='table') then
for k2,v2 in pairs(v1) do
if(type(v2)=='table') then
for k3,v3 in pairs(v2) do
if(k3=='uniformResourceIdentifier') then
table.insert(webIDs, v3:data())
end
end
end
end
end
end
end
return webIDs[1]
}
proxy_set_header X-WebID-URI $webid_uri;
}
Let me know if it can be improved.

How to make Postfix recive mails on main domain

How can I make in postfix recive mail on my domain?
ex. here I wont revice mail: neko#domain.com not like this: neko#mail.domain.com
Here is how I put in main.cf, but dosn't work
mydomain = domain.com
myorigin = $mydomain
Any solution?
take a closer look at mydestination in main.cf:
http://www.postfix.org/postconf.5.html#mydestination
here is an example, main.cf:
smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no
myhostname = mail.domain.com
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain
virtual_mailbox_domains = domain.com

How to get request’s HTTP headers with Socket.io?

I have an Express app running behind Nginx, so when I try to get the user’s IP, I always get 127.0.0.1 instead of the real one, which is set by Nginx in the X-Real-IP header. How do I get this header? Is there a way to have it via the socket object?
The code would be basically like that:
io.sockets.on( 'connection', function( socket ) {
var ip = /* ??? */;
/* do something with the IP…
… some stuff …
*/
});
To get the IP when you're running behind NGINX or another proxy:
var ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
or for Socket.IO
client.handshake.headers['x-forwarded-for'] || client.handshake.address.address;
From: http://www.hacksparrow.com/node-js-get-ip-address.html

Nodejs Server Hostname

Ok, so it seems pretty easy in Node.js to get the hostname of the request being made to my server:
app.get('/', function(req,res){
console.log(req.headers.host);
});
Is there an easy way to determine the hostname of my actual http server? For example, my server is running at the address http://localhost:3000 - can I programatically determine this address? I am using expressjs.
Yes you can using the;
var express = require('express'),
app = express(),
server = require('http').createServer(app);
server.listen(3000, function(err) {
console.log(err, server.address());
});
should print
{ address: '0.0.0.0', family: 'IPv4', port: 3000 }
you can also retreive the hostname for the os by the following;
require('os').hostname();

how to "allow from hostname" in nginx config

I'm currently doing this in my nginx.conf:
allow 1.2.3.4;
deny;
What I'd really like to do is this:
allow my.domain.name;
deny;
I.e., I want nginx to do an A record lookup on my.domain.name at the time of the request, and if it matches the IP that the request is coming from, then allow it. I don't see any built-in mechanism to do this however. Anybody have a native way to do this before I start coding something custom?
ngx_http_rdns_module does what you need: https://www.nginx.com/resources/wiki/modules/rdns/ (https://github.com/flant/nginx-http-rdns)
Summary
This module allows to make a reverse DNS (rDNS) lookup for incoming connection and provides simple access control of incoming hostname by allow/deny rules (similar to HttpAccessModule allow/deny directives; regular expressions are supported). Module works with the DNS server defined by the standard resolver directive.
Example
location / {
resolver 127.0.0.1;
rdns_deny badone\.example\.com;
if ($http_user_agent ~* FooAgent) {
rdns on;
}
if ($rdns_hostname ~* (foo\.example\.com)) {
set $myvar foo;
}
#...
}
This answer is an alternative which let resolution of domain out of nginx but targets the exact same goal, being able to have resolved ips included in nginx configuration.
1) Create a file allowed-domain.list which contains the domains you want to grant access to :
jean-paul.mydomain.com
rufus.mydomain.com
robert.mydomain.com
2) Create a bash script domain-resolver.sh which do the lookup for you :
#!/usr/bin/env bash
filename="$1"
while read -r line
do
ddns_record="$line"
if [[ ! -z $ddns_record ]]; then
resolved_ip=`getent ahosts $line | awk '{ print $1 ; exit }'`
if [[ ! -z $resolved_ip ]]; then
echo "allow $resolved_ip;# from $ddns_record"
fi
fi
done < "$filename"
3) Give the right permission to this script chmod +x domain-resolver.sh
4) Add a cron job which produces a valid nginx configuration and restarts nginx :
#!/usr/bin/env bash
/pathtoscript/domain-resolver.sh /pathtodomainlist/allowed-domain.list > /pathtooutputdir/allowed-ips-from-domains.conf
service nginx reload > /dev/null 2>&1
This can be a #daily job or you can have it run every hour, minute, sec...
5) Update your nginx configuration to take this output into account :
include /pathtooutputdir/allowed-ips-from-domains.conf;
deny all;
You can improve this adding an ip format check, prevent ipv6 if you don't want it, group everything in a single file...
There is no such feature in official distribution of nginx. Beacause it may heavily reduce performance.
Third party modules http://wiki.nginx.org/3rdPartyModules also doesn't contain this feature.
You can use lua script.
You need to install nginx-mod-http-lua and lua-nginx-dns modules.
The example nginx lua script will be:
location /test/ {
access_by_lua_block {
local resolver = require "nginx.dns.resolver";
local r, err = resolver:new {
nameservers = { "8.8.8.8", "1.1.1.1" },
retrans = 5, -- timeout retransmits
timeout = 500, -- 500msec
no_random = true, -- always start from the first name server
};
if not r then
ngx.log(ngx.ERR, "failed to instantiate the DNS resolver: " .. err)
return
end
local answers, err, tries = r:query("my.domain.name", nil, {});
if not answers then
ngx.log(ngx.ERR, "failed to query the DNS server: " .. err)
return
end
if answers.errcode then
ngx.log(ngx.ERR, "server returned error code: " .. answers.errcode .. ": " .. answers.errstr)
return;
end
for i, ans in ipairs(answers) do
if ans.address == ngx.var.remote_addr then
return
end
end
ngx.log(ngx.ERR, "Not allow IP : " .. ngx.var.remote_addr);
ngx.exit(ngx.HTTP_FORBIDDEN);
}
}
you can add this to return not found for any domain that do not match with yours
if ($host !~* (yourhostname.com)) {
return 404;
}

Resources