Accept INVITE only after REGISTER - asterisk

I run my own sip server (asterisk). Apparently my sip server allows to perform an INVITE without doing any REGISTER first. This leads to lots of unsuccessful attacks on my server. IS there any way to allow INVITE requests only from a successfully REGISTERed clients? Through asterisk or iptables?

You need change allowguest parameter to no in your sip.conf.
Check the link below for more tips about security in asterisk:
http://blogs.digium.com/2009/03/28/sip-security/

My study so far tells me that REGISTER is only for asterisk to reach or forward the INVITES but not to authenticate an INVITE request. When an INVITE comes, asterisk tries to check the given user name and if its a valid one, it sends a 407 (Authentication required) back to the client. Then client inserts the password (encrypted) in the response and sends INVITE2 to server. Now server authenticates the user and when credentials match, proceeds with establishing the call.
Conclusion: An INVITE has no relation with REGISTER and so my idea of restricting only REGISTERED clients to send an INVITE is not possible.
As a workaround, I have written my own script. Source is at https://github.com/naidu/JailMe

Consider a real Session Border Controller which pays for itself quickly when you get hacked. However, if you want a "good enough" option then read on:
There is an iptables module called "string" which will search a packet for a given string. In the case of SIP we expect to see "REGISTER" in the first packet from any given address, so combine this with -m state --state NEW or something similar. After that, we would want keep-alive happening to ensure that connection tracking remains open (usually Asterisk sends OPTIONS, but it can send empty UDP). You want that anyway in case the client is behind NAT.
It's not the ideal solution, because iptables cannot figure out whether a registration has been successful, but at least we can insist the other guy makes an attempt at registration. One of the answers linked below shows use of the string module in iptables:
https://security.stackexchange.com/questions/31957/test-firewall-rules-linux
You could also put an AGI script into your dialplan that does some additional checking, potentially looking at IP address and whether the extension is registered... ensure the INVITE comes from the same source IP.

Fail2Ban is an easy way to block unwanted traffic! fail2ban check system logs for failed attempts, if there are too many (exceeding defined threshold) failed attempts in specified time from some remote IP then Fail2Pan consider it as attack, and then add that IP address in iptables to block any type of traffic from it. following links can help
http://www.voip-info.org/wiki/view/Fail2Ban+(with+iptables)+And+Asterisk
http://www.markinthedark.nl/news/ubuntu-linux-unix/70-configure-fail2ban-for-asterisk-centos-5.html

Related

How to encrypt gRPC connections without certificates?

I'm going to be using gRPC for a device to device connection over a network (my device will be running Linux and collecting patient data from various monitors, gRPC will be used by a Windows client system to grab and display that data).
I obviously want to encrypt the data on the wire, but dealing with certificates is going to be a problem for various reasons. I can easily have the server not ask for the client cert, but so far I've been unable to find a way around the client validating the server's cert.
I've got several reasons I don't want to bother with a server cert:
The data collection device (the gRPC server) is going to be assigned an IP and name via DHCP in most cases. Which means that when that name changes (at install time, or when they move the device to a different part of the hospital), I have to automatically fixup the certs. Other than shipping a self-signed CA cert and key with the device, I don't know how to do that.
There are situations where we're going to want to point client to server via IP, not name. Given that gRPC can't do a cert for an IP (https://github.com/grpc/grpc/issues/2691), this becomes a configuration that we can't support without doing something to give a name to a thing we only have an IP for (hosts file on the Windows client?). Given the realities of operating in a hospital IT environment, NOT supporting use of IPs instead of names is NOT an option.
Is there some simple way to accommodate this situation? I'm far from an expert on any of this, so it's entirely possible I've missed something very basic.
Is there some simple way to set the name that the client uses to check the server to be different than the name it uses to connect to the server? That way I could just set a fixed name, use that all the time and be fine.
Is there some way to get a gRPC client to not check the server certificate? (I already have the server setup to ignore the client cert).
Is there some other way to get gRPC to encrypt the connection?
I could conceivably set things up to have the client open an ssh tunnel to the server and then run an insecure gRPC connection across that tunnel, but obviously adding another layer to opening the connection is a pain in the neck, and I'm not at all sure how comfortable the client team is going to be with that.
Thanks for raising this question! Please see my inline replies below:
I obviously want to encrypt the data on the wire, but dealing with
certificates is going to be a problem for various reasons. I can
easily have the server not ask for the client cert, but so far I've
been unable to find a way around the client validating the server's
cert.
There are actually two types of checks happening on the client side: certificate check and the hostname verification check. The former checks the server certificate, to make sure it is trusted by the client; the latter checks the target name with server's identity on the peer certificate. It seems you are suffering with the latter - just want to make sure because you will need to get both of these checks right on the client side, in order to establish a good connection.
The data collection device (the gRPC server) is going to be assigned
an IP and name via DHCP in most cases. Which means that when that name
changes (at install time, or when they move the device to a different
part of the hospital), I have to automatically fixup the certs. Other
than shipping a self-signed CA cert and key with the device, I don't
know how to do that.
There are situations where we're going to want to point client to
server via IP, not name. Given that gRPC can't do a cert for an IP
(https://github.com/grpc/grpc/issues/2691), this becomes a
configuration that we can't support without doing something to give a
name to a thing we only have an IP for (hosts file on the Windows
client?). Given the realities of operating in a hospital IT
environment, NOT supporting use of IPs instead of names is NOT an
option.
gRPC supports IP address(it is also mentioned in the last comment of the issue you brought up). You will have to put your IP address in the SAN field of server's certificate, instead of the CN field. It's true that it will be a problem if your IP will change dynamically - that's why we need DNS domain name, and set up the PKI infrastructure. If that's a bit heavy amount of work for your team, see below :)
Is there some simple way to accommodate this situation? I'm far from
an expert on any of this, so it's entirely possible I've missed
something very basic.
Is there some simple way to set the name that the client uses to check
the server to be different than the name it uses to connect to the
server? That way I could just set a fixed name, use that all the time
and be fine.
You can directly use IP address to connect, and override the target name in the channel args. Note that the overridden name should match the certificate sent from the server. Depending on which credential type you use, it could be slightly different. I suggest you read this question.
Is there some way to get a gRPC client to not check the server
certificate? (I already have the server setup to ignore the client
cert).
Is there some other way to get gRPC to encrypt the connection?
Note that: Even if you don't use any certificate on the wire, if you are sure the correct credential type(either SSL or TLS) is used, then the data on the wire is encrypted. Certificate helps you to make sure the endpoint to which you are connecting is verified. Failing to use certificates will leave your application to Man-In-The-Middle attacks. Hope this can help you better understand the goals and make the right judgement for your team.

Is it possible to detect whether a request is truly from localhost or is forged to "look like" from localhost in application layer?

Based on my understanding, there are some tools that can send a request from an IP address and make the request appear to servers like from another IP address, including from localhost.
Now I have a server with a specific API that only allows requests from localhost but has some other APIs that allow requests from the internet.
The only way I can think of is to set the firewall so that any incoming packet will be blocked if the destination contains the "localhost only" API name. However this forces me to design my server in such a way that no other APIs has a substring name of the "localhost only" API. This means the "localhost only" API cannot have a short name and can be a risk if I forget this fact and/or the code is maintained by other people in the future.
Ideally, I want to distinguish whether a request truly comes from localhost at application layer and if not so block further processing of the API.
What I want to know is whether this is possible or not, in terms of networking.

Get client's ip at user creation in Meteor

I'm creating a custom sign-in/sign-up in Meteor because I need to check the email format and more importantly to add a recaptcha in the sign-up form, which requires the client's ip.
So I plan to verify the captcha in Accounts.validateNewUser, but I cant figure out how to get the client's ip here.
I read an answer on how to do that, but it's not where I want to. I checked Meteor.default_server.sessions which contains all the sessions/sockets on the server. They contain information about headers, ips of all sockets. Each one has interesting stuff like:
pathname: "/sockjs/375/ibmrlwb2/xhr"
prefix: "/sockjs"
protocol: "xhr-polling"
remoteAddress: "127.0.0.1"
remotePort: 42009
But without knowing which socket is the current one, I cannot determine which ip of the current request is.
How can I know the current request url to the server? With that I can check with all the sockets on the server to infer the client's ip.
Or just simply how can I get the client's ip on the server?
I'm the maintainer of the user-status package mentioned in the other answer.
Recent/upcoming versions of Meteor have better support for managing connections as well as built-in support for grabbing IP addresses. Combined with the fact that login hooks were just merged into the devel branch today, you should be able to either handle this directly or use something that we'll add to the user-status package.
Feel free to open a pull request if there is something you need.
Getting the client's ip can be done with the user-status package. You can either use package or look through the code and see how it is being done.

What are the main security considerations when opening up port 25 and/or 587 for email delivery?

I am about to setup SmarterMail v9.0 on our Windows 2008 server (IIS7) and would first like to know what some security considerations are when opening up port 25 and/or 587 - ie how to prevent relaying, etc.
Thank you.
You must not accept email from untrusted users/sources which is not bound for domains you control.
An open relay is a mail server which allows anyone on the Internet to email anyone else, without verifying that either the source or the destination is known - thus, a relay.
You can check that the source is known by looking for a trusted IP subnet, or by requiring authentication before mail can be sent (via LOGIN over TLS, GSSAPI [called "Integrated Windows Authentication" or whatever], X.509 client certs, or the like).
You can check that the destination is known by comparing it to the list of domains for which your mail server will be the "last stop" (or a relay to another domain you control).
Either a known source or a known destination should be sufficient, but you may also want to make sure that mail inbound for your domains is at least borderline valid (originates from a domain with an MX server, for instance).
Separately, you must be conscious of DoS issues (rate limit inbound mail), and the ability to use your server to send backscatter spam. Backscatter is when I connect to your mail server and say, "why yes, I am unsuspecting_target#not_my_domain.com, please queue up this message for not_an_address#yourdomain.com". Then your mail server delivers a "bounce" message to the unsuspecting target. To mitigate this, you can verify that the recipient is known before accepting mail, or limit the rate at which mail can be accepted from one host, or try to check that the host delivering a message is authorized to use that envelope sender.
These are all well-solved problems.

Postfix and sending incoming emails to script instead of sending

I want to use Postfix to accept incoming emails and have it send them to an external Python script which parse them and add them to a database.
I read that this could be done via a Policy file.
My first question is what should the policy file return to have Postfix delete the email from the queue with a success message to the sender.
My second question is can I use the Policy file to validate the SMTP authentication that was sent by the client? If not, is there any way of having it use an external script to validate the login?
Thanks!
Christian
If you need SMTP authentication anyway and just want a script to act as MDA, I think you can do it simply by
setting mailbox_command = /path/to/my/script in /etc/postfix/main.cf and configuring an authentication scheme. If you have dovecot running, too, I can recommend having postfix authenticate via dovecot, which is very configurable when it comes to SASL authentication.
Update
Since you will be having plaintext passwords going over the wire (assuming this service is reachable from the network), I recommend permitting authentication only over an encrypted line. The configuration I'm going to show will still accept mails for which the server is the destination without authentication. As far as I know, that behaviour is mandated by an RFC for SMTP servers which are reachable from the internet.
Announce SASL authentication only over encrypted connections
smtpd_tls_auth_only=yes
Don't require everyone to talk to you over an encrypted channel
smtpd_tls_security_level=may
SASL boilerplate
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_local_domain = $mydomain
For whom to accept mail. This is worked left to right, until a permitting or denying rule is encountered. Fallback behaviour would be to permit.
smtpd_recipient_restrictions = permit_auth_destination, reject_plaintext_session, permit_sasl_authenticated, reject
permit_auth_destination as first rule would make sure that clients may deliver mail to users for which I feel responsible unauthenticated. The clients may choose whether to use TLS or not.
reject_plaintext_session as second rule makes sure that all other rules further down the line can assume an ecrypted channel.
permit_sasl_authenticated is self-explanatory
reject as last rule basically changes the default policy to "deny".
If you don't want to accept mails without SMTP authentication, you may want to drop the first rule of smtpd_recipient_restrictions.
Not shown is the configuration of the SSL certificate and how to tell postfix about it (the latter of which is easy).

Resources