Jump to content

Shogun

Premium
  • Posts

    1361
  • Joined

  • Days Won

    77
  • Feedback

    0%

Everything posted by Shogun

  1. Country subnets are not constant. They change. If you want properly updated subnet lists, it may even cost you money. In any case, my point is a blacklist will have more IPs than a whitelist and therefore be slower to process, because there are more countries to block than not (your expected players are not going to be spread over half the world I presume) This is not trivial when you are being flooded.
  2. There was a time, when Metin2 was still a recent game, when it was fairly easy to perform Layer 7 attacks on FreeBSD servers, or even hack into them. Much software was shipped with insecure defaults, and it was expected from the user to properly secure it. This has changed, and now MySQL is only listening to localhost by default, Apache is for the most part an unnecessary relic from the past, root user cannot login to ssh, and so on. But there is a part of the structure that has always been extremely vulnerable: the website, particularly the cheap webhosts many people opt for when they need to use certain poorly written CMS or Forum software that doesn't play well with Nginx. Since the needs of a game server (payment, voting and so on) can hardly be covered by any off-the-shelf solution, there will often be a need for some php script directly pulling data from the database to show a player ranking, or similar functions. This script can be repeatedly hit by one or multiple IP addresses and eventually overload the MySQL database which your game happens to use as well; eventually, both your game server and website go down. And no, Cloudflare will not help you unless you pay money and/or configure it extensively and properly, a process I may explain some other time. Today we are going to introduce two extremely easy solutions to mitigate this sort of attack I described with the help of nginx and a bit of mysql. Two stage rate limiting The first technique is rate limiting. It involves throttling repeated request from the same IP, particularly to php files which are the ones that consume by far more resources in the server. Hitting anything else is unlikely to cause any harm. In order to enable rate limiting, first we must add in the http context a "zone" where IPs are saved: limit_req_zone $binary_remote_addr zone=www:10m rate=5r/s; This will create a 10 mb memory zone to store a log of connections; if any of them exceeds 5 requests per second, they will be refused with a 503 error. But for this to actually work we must add this extra line into the php part of the server context - just mind the first two line heres and ignore the others that are there for context: location ~ \.php$ { limit_req zone=one burst=20 delay=10; limit_req_status 444; try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; include fastcgi_params; } Besides specifying where to perform this rate limiting (.php files), the settings enabled here make the experience a bit smoother by allowing the client to send a burst of up to 20 requests/second before refusing subsequent requests. Finally, the delay parameter indicates that when the connection speed exceeds 10r/second, the subsequent requests will be served with a delay. The second limit_req_status line instructs to give an empty response (444) instead of the default 503 error to excess connections, slightly reducing the server resources needed to deal with the presumed attack. FastCGI cache: serving stale content Now this is all fine and well, but what happens if we are attacked from multiple IPs? The feared DDoS! Well, it depends on what our hypotetical php script is exactly doing. If it's simply pulling data from the Database, we can use the proxy cache to force NGINX to serve such pages from a cache and avoid making repeated connections to the database. Let's define our cache in the http context: fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=mycache:10m inactive=10m; fastcgi_cache_key "$request_method$host$request_uri"; fastcgi_cache_use_stale updating; The first line creates a cache zone in memory of 10 mb, and specifies that if there are no requests for 10 minutes, the cache will be refreshed anyway. The second line specifies the arguments to use for creating a key (a sort of hash) in the cache for this request. In practice this means that if, for example, the query string is different in two requests they will still be considered to be the same request and for caching purposes, as the query string is not part of this "key". And the third line and most relevant means that while the cache is updating, the client will not wait for said update to finish before serving the requested content;instead it will serve the outdated ("stale") version of the page. Since every request normally triggers a cache update, this technique reduces the number of times the php script is actually executed during a flood enormously. (On a side note, this setting also allows us to show stale content when the backend is not responding. This is exactly what Cloudflare does with its "offline mode". We can enable this behavior by adding further triggers:) fastcgi cache use stale updating error timeout invalid_header http_500 http_503; Finally and to use the cache we defined in a location (in this case it must be the php location since its a fastcgi cache) we add this. Second line specifies for how long a 200 OK response is valid; other response codes will not be cached: fastcgi_cache mycache; fastcgi_cache_valid 200 5m; The icing in the cake: limit MySQL connections by user What about scripts that UPDATE the database? Things can get nasty here, since there's no cache to speak of all we can do is limit the total amount of requests that can be made to the backend and the database. In this case, nginx is not going to help; instead, create a specific user for your website different from the game user in MySQL and set a strict limit of connections. This means such attack will not take down the database. create user 'website'@'someip' identified by 'somepassword'; grant usage on account.* to 'website'@'someip' with max_user_connections 10; As an extra measure you can set more strict rate limits for the most vulnerable POSTing scripts in nginx (register, login...). Be aware you need to place specific locations (such as login.php) above the wildcard *.php location in the nginx config: location /login.php { limit_req zone=one burst=5 delay=2; limit_req_status 444; fastcgi_pass unix:/var/run/php-fpm.sock; include fastcgi_params; } And that is all you need to prevent your php scripts from being flooded. Of course, that's only one of the vector attacks, but also the most overlooked, yet easiest to fix. PHP programmers may also add extra checks in their code for repeated connections - memcached is your friend. But that's outside of our scope here.
  3. Hello there! As you may know I am specialized in DDoS protection (both preventive and real-time) and systems administration with a focus on FreeBSD. I have 12 years experience in firewalls, scripting, mysql, mariadb and nginx. Due to the large number of requests for my services and a few scam attempts I decided to take a break and rethink my service offerings. Basically I will still offer my services but the way I bill them is different. I no longer offer any package but instead a two-stage process: 1) An initial assessment of your project and needs. I will ask questions about it and check a few things through Anydesk, and suggest a course of action and an approximate budget for it. At that point you may decide to hire me to take those actions or try to do it yourself or with someone else's help. The cost of this assessment is 100€, regardless of the length of this interview. I do not offer any sort of help without this preliminary step. 2) Implementing my suggested measures. This is billed at 30€ per hour. If I know you, you may pay me at the end of the job. Otherwise, I will ask you to pay part of the estimated cost in advance. If you think this is expensive you are not my target audience. You are however invited to check my numerous tutorials in this forum or my FreeBSD blog https://freebsdis.fun and try to do it yourself. I only aim to work with serious customers who appreciate the value of a secure system.
  4. Run this command: ifconfig vtnet0 -txcsum -rxcsum -rxcsum6 -txcsum6 See if anything changes (with pf on)
  5. Such attack is normally too weak to bring any server down. The problem most likely lies elsewhere. Please provide the output of ifconfig and specifically, there's something to consider since you are running off a virtual machine: [Hidden Content] You should also disable pf and see what happens then. Does the attack still bring the channel down? If not, then your problem is with VirtIO. If yes, I suggest you follow this tutorial by Papix which is actually a pretty good idea: Otherwise you can contact me on Discord if you want me to have a look at it myself for a small fee.
  6. Please use the -n option and exclude the ssh port. Otherwise the dump isn't useful. tcpdump -i vtnet0 -n -vvv port not <your ssh port number>
  7. Every server out there has an attack vector of some sort. Then it's all up to the patience and skill of the attacker. The real question here is: are you able to figure out what and how is hitting you? If the answer is yes then you can establish some sort of countermeasure. Even if it involves some discomfort for your users. There has been layer 7 attacks always, so you need to be more specific or provide tcpdump logs.
  8. Point 1. You have a botnet attacking you. In that botnet, there will be IP addresses from all over the world. If you can limit access to countries where you know your users will be, then you are leaving a part of the botnet out hence less packets hitting whatever they are trying to hit. But that's not the discussion here. PF is not a hardware firewall but it's usually and in the cases we discuss in this forum running on the same system you try to protect and consuming its resources while it processes rules. Hence it's in our interest that these rules are processed as quickly as possible. Given that the list of IPs or subnets we want to block is much larger than the list of subnets we want to allow, it makes sense to have PF check any connecting IP against the later list because that will be faster - and then block everything else.
  9. That won't survive a reboot. Assuming we are root and our shell is, as it's the default, csh: echo 'setenv EDITOR ee' >> /root/.cshrc
  10. It's a good strategy against botnets, but let's not forget that processing rules also consumes resources and comparing every IP against some large database might not be the greatest idea as a botnet with many members could potentially be able to take down your server faster than not using a geo block as pf becomes the bottleneck itself. It is more efficient in this scenario to whitelist the countries that we do want to allow and have a blanket block for everything else. Also what do you need to install wget for? FreeBSD has its own native utility, fetch.
  11. That's correct but to be precise you only need the motlist.txt and the msm files it refers to. Something worth noting, since this is one instance where we will use the same files both server and client side, is that FreeBSD unlike Windows is case sensitive so if a file is called SOMETHING.MSA and appears in motlist.txt as Something.msa it will not be found by the server. Also, FreeBSD ends lines with a LF (Line Feed) ASCII code while Windows adds both a CR (Carrier Return) and LF. FreeBSD reads CR as a strange character which may result in your text being misinterpreted. Accumulation value is only being read in the RUN motion, and its value should match the granny file, otherwise the mob will appear to reach you faster or slower than it actually is. Open the run gr2 file in Granny Viewer; in the animation list right click in your file and then “view in detail”. Click view sub-structure under “void ** TrackGroups", the numbers written in granny_real32 are your accumulation data.
  12. Most wholesome thing I've seen in this forum
  13. player.item_attr_rare
  14. There is no such thing. The source was only leaked once in late 2013.
  15. This path "/tmp/mysql.sock" is hardcoded in the source, but modern ports of MySQL and MariaDB use "/var/run/mysql/mysql.sock" instead. You have 3 options: 1. Edit the MySQL config to match what db expects (easy) First find your my.cnf file as the location may vary depending on which version and flavor of MySQL you have: find / -type f -name 'my.cnf' Edit the resulting file* and search for a line like similar to this one: socket = "/var/run/mysql/mysql.sock" Either add this line or change the existing one to read: socket = "/tmp/mysql.sock" then restart the MySQL server: server mysql-server restart 2. Edit the source to match current standards (proper) Search for the string "/tmp/mysql.sock" in the source and replace it with "/var/run/mysql/mysql.sock". 3. Not use sockets at all (desperate) If you can't get any of this to work, search for SOCKET in your CONFIG files and replace every occurence with 127.0.0.1 to use less efficient TCP connections instead. * If you find more than one my.cnf, you should probably edit /usr/local/etc/mysql/my.cnf as that is currently the standard location. Previously it was /usr/local/etc/my.cnf, earlier /var/db/mysql/my.cnf and even earlier, /etc/my.cnf Which one of these takes precedence may be hard to figure out but I had to mention this given the strange fascination Metin2 people have with using ancient versions of freely available software.
  16. There's no single "Metin2" set of files but generally speaking you'd need to install 32 bit compatibility libraries. As for system security: Create a non-root user. Put your game in his home directory. Add him to the wheel group. Create ssh keys for him. Disable Permit Root Login, Password Authentication, Challenge-Response Authentication, PAM in /etc/ssh/sshd_config so you can only login with this ssh-key. You can always use IPMI/KVM/etc on an emergency. Change the SSH port to some random high number between 32000 and 65000. Restart sshd_config. Do not bind mysql server to a public IP and if you have to, use an IP whitelist in PF or in a hardware firewall like OVH's. If you use Navicat and such, use SSH authentication. Do not leave port 3306 open to public. Do not bind db to a public IP, and if you have to, whitelist the necessary IPs. Install pf and set it up to accept only the necessary ports. If you have less than 15 ports that need opening, you can use the OVH firewall if you are in OVH. There's hundreds of exploits working on the original leaked source. Get some good files like martysama's. As for DDoS protection: use Cloudflare. Use origin pulls. Whitelist Cloudflare IPs. Set rate limits on NGINX. Set timeouts. Cache database accesses such as "Top Players" to not directly execute expensive database queries which are easy targets for DDoS. I could go on, but the only good answer here is, if you're serious about doing something, get someone who knows his stuff.
  17. There is a Shadowflag which does that for any property file except effects which never have shadows and trees which always do. In WE, it can be toggled by double clicking on an object in the list and checking/unchecking the Shadow box.
  18. It looks like a collection of random objects to be honest. Those funny plants are interesting though.
  19. Nice layout and the crimson trees are a simple way of giving personality to the map.
  20. ALTER USER 'user'@'host' IDENTIFIED BY 'newpassword';
  21. I am guessing that's chinese. Open your server's syserr and find that message (it will look like random characters) Copy and paste it into some text editor like sublime Change encoding to BIG5 (assuming it's chinese) Copy the resulting text into Google Translate
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.