VPSを保護する手順

このチュートリアルでは、Debian GNU / Linuxを使用して仮想プライベートサーバー(VPS)を準備および保護する方法を示します。 始める前に、特定のことが想定されています。

  1. あなたはGNU / Linuxに中級レベルの知識を持っています。
  2. SSH経由でアクセスできる個人用のVPSがあります。
  3. VPSには専用の外部ipv4があり、プロバイダーは250.250.250.155/250.250.0.0ブロックを所有しています。 (16)
  4. VPSでは、外部からのアクセスに対してhttp、https、およびsshサービスのみが有効になります。
  5. 外部DNSは通常、プロバイダーのパネルで実行されるため、有効になりません。 (2)
  6. スーパーユーザーとして機能します。

インストール

最初のステップとして、サーバーを更新し、必要ないくつかのパッケージをインストールしましょう。

#aptitude update&aptitude safe-upgrade#aptitude -RvW install dropbear gesftpserver sslh iptables-persistent ulogd fail2ban nginx-light apache2-utils dnsutils telnet ghostscript poppler-utils zip unzip unrar-free p7zip-full less multitail tee mc

コンフィギュレーション

次に、仕事用ユーザーを作成します。 サーバーでrootとして機能することは安全ではないため、最初に特別なユーザーを作成します。

adduser演算子usermod-aGsudo演算子

最初のコマンドはオペレーターユーザーを作成し、XNUMX番目のコマンドはそれをグループに追加します sudo、これにより、アプリケーションをルートとして実行できるようになります。

スーパーユーザーの権限を調整する

定期的に作業するために、ユーザーを使用します 演算子 以前に作成したスーパーユーザーとしてコマンド実行オプションを調整する必要があります。スーパーユーザーに対して、次のコマンドを実行します。

visudo

このコマンドは基本的にファイルの変更を許可します /etc/sudoers; これらの行を含める必要があります。

デフォルトenv_reset、timestamp_timeout = 0%sudo ALL =(ALL:ALL)ALL

最初の行で、オプションがデフォルト値に追加されます タイムスタンプ_タイムアウト これにより、sudoコマンドの実行時のパスワードの有効期限(分単位)を設定できます。 デフォルトは5ですが、次のXNUMXつの理由で安全でない場合があります。

  1. パスワードの有効期限が切れる前に誤ってコンピュータをログインしたままにしておくと、誰かが制限なしにスーパーユーザーとしてコマンドを実行する可能性があります。
  2. パスワードの有効期限が切れる前に、無知によって悪意のあるコードを含むアプリケーションまたはスクリプトを実行した場合、アプリケーションは、明示的な同意なしに、スーパーユーザーとしてシステムにアクセスする可能性があります。

そのため、リスクを回避するために、値をゼロに設定しました。つまり、sudoコマンドを実行するたびに、パスワードを入力する必要があります。 負の値を-1に設定すると、パスワードの有効期限が切れることはなく、希望とは逆の結果になります。

3行目では、sudoグループは、調整は可能ですが、通常のように、任意のコンピューターで任意のコマンドを実行できることが明確になっています。 (XNUMX)パスワードを入力する必要がないように、便宜上次のように行を入力する人がいます。

%sudo ALL =(ALL:ALL)NOPASSWD:ALL

ただし、前に説明したように、これは危険であるため、お勧めしません。

再起動を無効にする

セキュリティ上の理由から、キーの組み合わせを使用した再起動も無効にします Ctrl + Alt + Delキー、この行をファイルに追加する必要があります /etc/inittab:

ca:12345:ctrlaltdel:/ bin / echo "Ctrl + Alt + Delが無効になっています。"

OpenSSHをDropBearに置き換えます

ほとんどのVPSにはOpenSSHがインストールされています。これは確かに非常に便利ですが、OpenSSHのすべての機能を活用する必要がない限り、VPSのより軽量な代替手段があります。 ドロップベア、通常は通常の使用には十分です。 ただし、このアプリケーションの欠点は、統合されたSFTPサーバーが付属していないことです。そのため、最初にパッケージをインストールしました。 ゲスフトサーバー.

Dropbearを構成するには、ファイルを変更します / etc / default / dropbear 次のXNUMX行が含まれるようにします。

NO_START = 0 DROPBEAR_EXTRA_ARGS = "-w -p 127.0.0.1:22 -I 1200 -m"

最初の行は単にサービスを有効にし、XNUMX番目の行はいくつかのことを行います。

  1. ルートアクセスは避けてください。
  2. これにより、サービスはローカルインターフェイスのポート22でリッスンします(理由については後で説明します)。
  3. 待機時間(20分)を設定します。

SSLH

ポート22(SSH)はよく知られており、一般的にハッカーが最初に侵害しようとするものの443つであるため、代わりにポートXNUMX(SSL)を使用します。 このポートは、HTTPSを介した安全なブラウジングに使用されることがあります。

このため、sslhパッケージを使用します。これは、ポート443に到着するパケットを分析し、トラフィックのタイプがSSHかSSLかに応じて、内部でXNUMXつのサービスまたは別のサービスにルーティングするマルチプレクサにすぎません。

SSLHは、別のサービスがすでにリッスンしているインターフェイスでリッスンできません。そのため、以前にDropbearをローカルインターフェイスでリッスンさせました。

ここで行う必要があるのは、インターフェイスとそれがリッスンするポート、およびサービスのタイプに応じてパケットをリダイレクトする場所をsslhに指示することです。このために、構成ファイルを変更します。 / etc / default / sslh:

DAEMON = / usr / sbin / sslh DAEMON_OPTS = "-user sslh --listen 250.250.250.155:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile / var / run / sslh / sslh .pid "RUN =はい

最後に、サービスを再開します。

service ssh stop && service dropbear start && service sslh restart

前のコマンドの後、セキュアセッションが中断される可能性があります。その場合は、再度ログインするだけで十分ですが、今回は作業ユーザーでポート443を使用します。セッションが中断されない場合は、セッションを閉じて再開することをお勧めします。適切な値で。

すべてが正常に機能する場合は、rootとして機能し続け、必要に応じてOpenSSHをアンインストールします。

sudo su --aptitude-rパージopenssh-server

ファイアウォール

次に行うことは、ログをファイアウォールから別のファイルに分離することです /var/log/firewall.log さらなる分析を容易にするために、起動時にulogdパッケージをインストールしたのはそのためです。 このために、ファイルを編集します /etc/logd.conf 関連するセクションを調整するには:

[LOGEMU] file = "/ var / log / Firewall.log" sync = 1

次に、レコードローテーションファイルを変更します / etc / logrotate / ulogd 毎日のローテーション(日付付き)を維持し、圧縮されたサルボをディレクトリに保存します / var / log / ulog /:

/var/log/ulog/*.log /var/log/firewall.log {daily dateext Missingok compress delaycompress sharedscripts create 640 root adm postrotate /etc/init.d/ulogd reload mv /var/log/firewall.log-* .gz / var / log / ulog / endscript}

次に、以下を実行してnetfilterルールを作成します。

IPT = $(どのiptables)IPEXT = 250.250.250.155 IPEXTBLK = 250.250.0.0 / 16 IPBCAST = 255.255.255.255 $ IPT -F $ IPT -X $ IPT -Z $ IPT -A INPUT -i lo -j ACCEPT $ IPT- P INPUT DROP $ IPT -P FORWARD DROP $ IPT -P OUTPUT ACCEPT $ IPT -A INPUT -m state --state INVALID -j ULOG --ulog-prefix IN_INVALID $ IPT -A INPUT -p igmp -j ULOG --ulog -プレフィックスIN_IGMP $ IPT -A INPUT -m pkttype--pkt-typeブロードキャスト-jULOG --ulog-prefix IN_BCAST $ IPT -A INPUT -m pkttype--pkt-typeマルチキャスト-jULOG --ulog-prefix IN_MCAST $ IPT -A FORWARD -j ULOG --ulog-prefix FORWARD $ IPT -N ICMP_IN $ IPT -A INPUT!  -i lo -p icmp -j ICMP_IN $ IPT -A ICMP_IN -p icmp -f -j ULOG --ulog-prefix IN_ICMP_FRAGMENTED $ IPT -A ICMP_IN -p icmp -m icmp -m length!  -長さ28:1322 -j ULOG --ulog-prefix IN_ICMP_INVALIDSIZE $ IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-above 4 / sec --hashlimit-mode srcip --hashlimit-srcmask24- -hashlimit-name icmpflood -j ULOG --ulog-prefix IN_ICMP_FLOOD $ IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-upto 64kb / min --hashlimit-mode srcip --hashlimit-srcmask24- hashlimit-name icmpattack -j ULOG --ulog-prefix IN_ICMP_FLOOD $ IPT -A ICMP_IN -p icmp -m icmp -m u32!  --u32 "0x4&0x3fff = 0x0" -j ULOG --ulog-prefix IN_ICMP_ATTACK $ IPT -A ICMP_IN -p icmp -m icmp!  --icmp-type echo-r​​equest -m state --state NEW -j ULOG --ulog-prefix IN_ICMP_INVALID $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-r​​equest -j ULOG --ulog-プレフィックスIN_ICMP $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-r​​equest -m limit --limit 1 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-r​​eply -m limit --limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type destination-unreachable -m limit- limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type time-exceeded -m limit --limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type parameter-problem -m limit --limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -j RETURN $ IPT -N UDP_IN $ IPT -A入力!  -i lo -p udp -j UDP_IN $ IPT -A UDP_IN!  -私は!  -p udp -f -j ULOG --ulog-prefix IN_UDP_FRAGMENTED $ IPT -A UDP_IN -p udp -m udp --sport 53 -m長さ!  -長さ28:576 -j ULOG --ulog-prefix IN_UDP_DNS_INVALIDSIZE $ IPT -A UDP_IN -p udp -m udp --dport 53 -m -state --state NEW -j ULOG --ulog-prefix IN_UDP_DNSREQUEST $ IPT- UDP_IN -p udp -m udp --dport 53 -m -state --state NEW -j REJECT --reject-with icmp-port-unreachable $ IPT -A UDP_IN -p udp -m udp!  -スポーツ53!  -s $ IPEXTBLK!  -d $ IPBCAST -m state --state NEW -j ULOG --ulog-prefix IN_UDP $ IPT -A UDP_IN -p udp -m udp -m state --state ESTABLISHED、RELATED -j ACCEPT $ IPT -A UDP_IN -j RETURN $ IPT -N TCP_IN $ IPT -A入力!  -i lo -p tcp -j TCP_IN $ IPT -A TCP_IN!  -私は!  -p tcp -f -j ULOG --ulog-prefix IN_TCP_FRAGMENTED $ IPT -A TCP_IN -p tcp -m tcp --sport 53 -m state --state ESTABLISHED、RELATED -m length!  -長さ513:1500 -j ULOG --ulog-prefix IN_TCP_DNS_INVALIDSIZE $ IPT -A TCP_IN -p tcp -m tcp --dport 53 -m state --state NEW -j ULOG --ulog-prefix IN_TCP_DNS $ IPT -A TCP_IN -p tcp -m tcp --dport 53 -m state --state NEW -j REJECT --reject-with icmp-port-unreachable $ IPT -A TCP_IN -p tcp -m tcp -m multiport!  --dports 80,443 -m state --state NEW -j ULOG --ulog-prefix IN_TCP $ IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -m hashlimit- hashlimit-最大4 /秒--hashlimit-バースト16--hashlimit-mode srcip --hashlimit-name navreq -j ACCEPT $ IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m state-状態ESTABLISHED-m connlimit!  --connlimit-16以上-jACCEPT $ IPT -A TCP_IN -p tcp -m tcp -mマルチポート! 

以前の構成では、VPSは適切に保護されている必要がありますが、必要に応じてもう少し保護して、より高度なルールを使用できます。

すべてのVPSでnetfilter用の追加モジュールをインストールできるわけではありませんが、非常に便利なモジュールは PSD、これにより、ポートスキャンを回避できます。 残念ながら、このモジュールはデフォルトではnetfilterに統合されていないため、特定のパッケージをインストールしてからモジュールをビルドする必要があります。

aptitude -RvW install iptables-dev xtables-addons-source module-assistant module-assistant --verbose --text-mode auto-install xtables-addons-source

上記が完了したら、次のようなルールを追加できます。

iptables -A INPUT -m psd --psd-weight-threshold 15 --psd-delay-threshold 2000 --psd-lo-port-weight 3 --psd-hi-ports-weight 1 -j ULOG --ulog-プレフィックスIN_PORTSCAN

前のルールは基本的に、3未満のポートにアクセスしようとするたびに1024ずつ増加し、1より高いポートにアクセスしようとするたびに1023ずつ増加し、このカウンターが15に達すると増加するカウンターを作成することを意味します。 20秒未満の期間、パッケージはによって登録されます ウログ ポートスキャンの試みとして。 パケットはまだ一度に破棄できますが、この場合は使用する予定です fail2ban、後で構成します。

ルールを作成したら、それらを永続化するために特定の予防措置を講じる必要があります。そうしないと、サーバーを再起動したときにルールが失われます。 これを実現するにはいくつかの方法があります。 このチュートリアルでは、最初にインストールしたiptables-persistentパッケージを使用します。このパッケージには、ルールが格納されています。 /etc/iptables/rules.v4 y /etc/iptables/rules.v6 ipv6の場合。

iptables-保存> /etc/iptables/rules.v4

実際、キューバでのipv6の使用はまだ普及していませんが、いくつかの基本的なルールを作成することはできます。

IPT = $(ip6tables)$ IPT -P INPUT DROP $ IPT -P FORWARD DROP $ IPT -P OUTPUT ACCEPT $ IPT -A INPUT -i lo -j ACCEPT $ IPT -A INPUT! -i lo -m state --state ESTABLISHED、RELATED -j ACCEPT unset IPT

これらのルールは永続化することもできます。

ip6tables-保存> /etc/iptables/rules.v6

最後に、セキュリティを強化するために、ファイアウォールのレジストリをクリーンアップし、サービスを再起動します。

echo -n> /var/log/firewall.log service logrotate restart service ulogd restart service iptables-persistent restart

nginx

VPSは通常実際のサーバーと比較してRAMの量が少ないため、NginxをWebサーバーとして使用します。したがって、Apacheよりも軽いものを使用すると一般的に便利です。

Nginxを構成する前に、HTTPSで使用するための証明書(パスワードなし)を作成します。

cd / etc / nginx openssl genrsa -des3 -out cert.key 4096 cp -v cert.key cert.key.original openssl req -new -key cert.key -out cert.csr openssl rsa -in cert.key.original- out cert.key openssl x509 -req -days 365 -in cert.csr -signkey cert.key -out cert.crt

これが完了したら、ユーザー「elusuario」のパスワードファイルを作成します。

htpasswd -c.htpasswdユーザー

次に、ファイルを変更します / etc / nginx / sites-available / default デフォルトのサイト設定を設定します。 次のようになります。

サーバー{server_namelocalhost; index index.html index.htm default.html default.htm; ルート/変数/ www; location / {#URIが見つからない場合に、検証の順序とロードするページを設定しますtry_files $ uri $ uri / /index.html; }}サーバー{リッスン127.0.0.1:443; server_name localhost; index index.html index.htm default.html default.htm; ルート/変数/ www; ssl on; ssl_certificate cert.crt; ssl_certificate_key cert.key; ssl_session_timeout 5m; #TLSを介してのみHTTPSを有効にします(SSLよりも安全です)ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #高強度[HIGH]暗号を優先し、#中強度[MEDIUM]暗号をリストの最後に移動し、#低強度[LOW]暗号(40ビットおよび56ビット)を無効にします。エクスポートアルゴリズム[EXP]#認証なしでnull暗号[eNULL]を無効にする[aNULL]、SSL(バージョン2および3)およびDSS(1024ビットまでのキーのみを許可)ssl_ciphers HIGH:+ MEDIUM:!LOW:!EXP: !aNULL:!eNULL:!SSLv3:!SSLv2:!DSS; #サーバーの暗号化方法を優先します(デフォルトではクライアントが使用されます)ssl_prefer_server_ciphers on; location / {#認証を有効にするauth_basic "Login"; auth_basic_user_file /etc/nginx/.htpasswd; #URI try_files $ uri $ uri / = 404が見つからない場合に、ロードする検証順序とページコードを設定します。 #認証されたユーザーの自動インデックス作成のインデックスの作成を許可します。 autoindex_exact_size off; autoindex_localtime on; }}

構成が正しいことを確認します。

nginx -t

最後に、サービスを再起動します。

サービスnginx restart

Fail2Ban

Fail2Banの構成を開始する前に、セキュリティを強化するために、サービスを停止してレジストリをクリーンアップします。

fail2ban-クライアント停止エコー-n> /var/log/fail2ban.log

次に、構成ファイルを作成します /etc/fail2ban/jail.local 次のカスタムコンテンツを使用します。

#カスタム構成ファイル/etc/fail2ban/jail.local# [デフォルト] findtime = 43200; 12時間の禁止時間= 86400; 1日maxretry = 3; 禁止は、4回目の試行後に有効になります[ssh] enabled = false [nginx-auth] enabled = true filter = nginx-auth action = iptables-multiport [name = NoAuthFailures、port = "http、https"] logpath = / var / log / nginx * / *エラー* .log [nginx-badbots] enabled = true filter = apache-badbots action = iptables-multiport [name = BadBots、port = "http、https"] logpath = / var / log / nginx * /*access*.log bantime = 604800; 1週間maxretry = 0 [nginx-login] enabled = true filter = nginx-login action = iptables-multiport [name = NoLoginFailures、port = "http、https"] logpath = / var / log / nginx * / *アクセス*。ログ禁止時間= 1800; 30分[nginx-noscript] enabled = true action = iptables-multiport [name = NoScript、port = "http、https"] filter = nginx-noscript logpath = /var/log/nginx*/*access*.log maxretry = 0 [nginx-proxy] enabled = true action = iptables-multiport [name = NoProxy、port = "http、https"] filter = nginx-proxy logpath = /var/log/nginx*/*access*.log bantime = 604800 ; 1週間maxretry = 0 [firewall]有効= trueアクション= iptables-multiport [名前= Firewall]フィルター= firewall logpath = /var/log/firewall.log maxretry = 0

これが完了したら、ディレクトリに作成します /etc/fail2ban/filters.d/ 次のファイル:

#/ etc / fail2ban / filter.d / nginx-auth.conf#認証フィルター#基本認証を使用した認証に失敗したIPをブロックします#[定義] failregex =基本認証にユーザー/パスワードが指定されていません。*クライアント: ユーザー。*が見つかりませんでした。*クライアント: ユーザー。*パスワードの不一致。*クライアント: ignoreregex =
#/ etc / fail2ban / filter.d / nginx-login.conf#ログインフィルター#Webアプリケーションのログインページを使用した認証に失敗したIPをブロックします#HTTP 200 + POST /セッションのアクセスログをスキャンします=>ログインに失敗しました#[定義] failregex = ^ -。* POST /セッションHTTP / 1 \ .. "200 ignoreregex =
#/ etc / fail2ban / filter.d / nginx-noscript.conf#Noscript filter#.php、.pl、.exe、その他の面白いスクリプトなどのスクリプトを実行しようとするIPをブロックします。 #一致例:#192.168.1.1 --- "GET /something.php# [定義] failregex = ^ -。* GET。*(\。Php | \ .asp | \ .exe | \ .pl | \ .cgi | \ scgi)ignoreregex =
#/ etc / fail2ban / filter.d / proxy.conf#プロキシフィルター#サーバーをプロキシとして使用しようとするIPをブロックします。 #一致例:#192.168.1.1 --- "GET http://www.something.com/# [定義] failregex = ^ -。* GEThttp。* Ignoreregex =
#/ etc / fail2ban / filter.d / firewall.conf#ファイアウォールフィルター#[定義] failregex = ^。* IN_(INVALID | PORTSCAN | UDP | TCP |)。* SRC = 。* $ ignoreregex =

最後に、サービスを開始し、構成をロードします。

fail2ban-service -bfail2ban-クライアントのリロード

検証

最後のステップとして、次のレコードを表示できます。 テール-f o マルチテール–フォローオール。 実際、後者のアプリケーションには、複数のファイルを同時に表示できるという利点があり、基本的な構文の強調表示が提供されます。

電子メールアカウントがVPSで構成されていない場合は、マルチテールの開始時に表示される警告メッセージを無効にすることをお勧めします。そのために、次のコマンドを実行します。

echo "check_mail:0">〜/ .multitailrc

実際、「flog」などの短いコマンドでログをすばやく表示するためのエイリアス(4)を作成することもできます。

エイリアスflog = 'multitail --follow-all /var/log/firewall.log /var/log/fail2ban.log'

1)これらは架空の値です。
2)他のサービスの有効化は、その仕組みを理解すれば簡単です。
3)詳細については、mansudoersを実行してください。
4)オプションで、〜/ .bash_aliasesファイルに追加できます。


コメントを残す

あなたのメールアドレスが公開されることはありません。 必須フィールドには付いています *

*

*

  1. データの責任者:MiguelÁngelGatón
  2. データの目的:SPAMの制御、コメント管理。
  3. 正当化:あなたの同意
  4. データの伝達:法的義務がある場合を除き、データが第三者に伝達されることはありません。
  5. データストレージ:Occentus Networks(EU)がホストするデータベース
  6. 権利:いつでも情報を制限、回復、削除できます。

  1.   MSX

    面白いことがいくつかあります、+ 1

  2.   ゆきてる

    構成内の@Hugoこの行:

    ssl_protocols SSLv3 TLSv1;

    そのプロトコルはもはや安全ではないので、SSLv3を削除します。DebianJessieでも、その理由でそのプロトコルの使用を回避するように多くのサービスが構成されています。

    ここのトピックに関する情報:

    https://www.linode.com/docs/security/security-patches/disabling-sslv3-for-poodle
    http://disablessl3.com/

    1.    ヒューゴー

      アイデアは、実際にはHTTPSを介して主要なサービスを提供することではなく、必要に応じてHTTPSで使用する可能性を失うことなく、SSHでポート443を使用する方法を説明することでしたが、警告に感謝します。

      とにかく、私はnginx構成を少し変更するために記事を更新し、偶然にも、この暗号化メカニズムで物事をもう少し明確にし、いくつかのマイナーエラーを修正するためにいくつかのコメントを含めました。

  3.   ダニエルPZ

    Muchas gracias por este estupendo tutorial, ahora lo pondré en practica! :D, Sigan así DesdeLinux, siempre me sorprenden, Saludos desde Perú.

  4.   <XNUMXxCXNUMX><XNUMXxXNUMX> アンドデクエラ

    共有のためにありがとうございました。

  5.   フェルナンド

    非常に良いガイドであり、このブログを始めた今は真珠から来ていますが、最初のvpsをマウントしようとしていて、まだ多くの問題がありますが、この記事は多くの疑問、感謝、挨拶から私を連れ出しました