chore(i18n): Fix image problems

The images in an Indonesian article are not displayed
if no primary language (in this case, English) is present.
Adding the main primary language fixes the image rendering problem.
This commit is contained in:
Cristian Ditaputratama 2024-06-07 20:12:49 +07:00
parent 8d08ace495
commit 5d0965673d
Signed by: ditatompel
GPG key ID: 31D3D06D77950979
12 changed files with 2050 additions and 0 deletions

View file

@ -0,0 +1,139 @@
---
title: "Password 101: Best Practices for Secure Online Living"
description: "Discusses how you should create and treat your passwords as well as tips for using a password manager to make it easier to manage unique and random passwords on every site / application you use."
summary: "Discusses how you should create and treat your passwords as well as tips for using a password manager to make it easier to manage unique and random passwords on every site/application you use."
date: 2022-09-09T19:47:48+07:00
lastmod:
draft: false
noindex: false
featured: true
pinned: false
series:
# -
categories:
- Security
tags:
- Bitwarden
- KeepassXC
images:
authors:
- ditatompel
---
The password is a crucial aspect of online security. This article explores how to create and manage strong, unique passwords, as well as [tips for using an open-source password manager](#tips-for-using-a-password-manager) to securely store and access your credentials on various websites and apps.
So, how should we treat and create good passwords? Here are 5 crucial points (in my opinion) regarding passwords and tips for using **a password manager**.
## Never Share Your Password with Anyone
I'd like to remind you of one of the key differences between **_private_** and **_secret_** according to the [_Cypherpunk's Manifesto_](https://www.activism.net/cypherpunk/manifesto.html).
**A secret is something that only you know**, nobody else should know. On the other hand, **private is something you don't want the whole world to know**. It's like your home address, phone number, or the shape of your personal belongings... (you get the idea). Your closest acquaintances may be aware of certain private aspects about yourself.
A password, however, is a secret matter that **only you** should know. Think of sharing your password as betraying yourself something to be avoided at all costs. Not even a trusted partner or family member deserves access to this secret information.
## Never Use the Same Password
Many of my friends still use the same passwords across various websites. When you use the same password across multiple websites and apps, you're inviting potential disaster into your digital life.
The rule is clear: use separate passwords for each website and app. Why? Because if those credentials were to leak into the public domain, the consequences would be severe.
Even the most secure-looking websites can fall victim to data breaches. Even well-known websites have made mistakes before like [**Facebook** was once stored its users' passwords in plain text](https://techcrunch.com/2019/03/21/facebook-plaintext-passwords/). :clap: :shit:
Imagine waking up one morning to find that your personal info has been compromised, or worse your financial accounts have been drained. It's a nightmare scenario that can be avoided by using unique passwords for each online account.
The best-designed systems can have flaws, and those operated by well-intentioned and experienced humans are not immune to mistakes and imperfections. Therefore, never use the same password and enable two-factor authentication (2FA) to make it even safer.
## Use a Long and Complex Password
![Password Brute Force Table](feature-password-brute-time-table.png#center "Password Brute Force Table")
The table above provides information on how long it takes to obtain a plain-text password using **an Nvidia GeForce 1080**, assuming we can perform a brute-force attack 30 million times in one second.
Of course, this simulation varies depending on the hardware's capabilities and the hash algorithm used. Use a **minimum of 12 random characters containing numbers, symbols, uppercase letters, and lowercase letters**. The longer it is, the better, as technology and hardware capabilities develop rapidly.
> By **a truly random password**, I mean one that is completely unrecognizable as a word, whether noun or adjective. For example: `i7#xYkU9Txd@5Y`
> Although there are other factors that can shorten the time needed to obtain a plain-text password due to **hash collisions** (see [Wikipedia Hash Collision](https://en.wikipedia.org/wiki/Hash_collision)), using a complex password at least reduces the options available to crackers, making it harder for them to easily obtain our plain-text password.
## Avoid Using Personal Identifiers in Your Passwords
Many people tend to choose and combine personal information in their passwords. For example:
- **Date of birth**: ditatompel09111978 or 19781109dita
- **Address**: tompelBrooklyn12St
- **Phone Number**: dita7576
- **Hobby**: Fap3x24
_\*Forget the last one_ :speak_no_evil:.
Information that can be inferred from this data can be exploited for a [_Brute Force_](https://en.wikipedia.org/wiki/Brute-force_attack) attack on your password. So, **use a password that is difficult to guess and completely random**.
## Don't Store Your Passwords Within Browser's Built-in Password Management or Unencrypted Document
Avoid storing your passwords within a browser's built-in password management feature. Most mainstream browsers' built-in password management features do not implement encryption or additional authentication measures, so your password may be stored in plaintext on your device. If someone borrows our PC/laptop, it only takes a few seconds to retrieve the stored password.
Similarly, avoid storing passwords on built-in phone features as well, and instead use an **Open-Source Password Manager** that I will discuss later in this article.
## Changing Passwords Regularly is No Longer Relevant
![OTP according to Kominfo](pak-menkom-johnny-ngomong-otp-harus-selalu-diganti-lmao.jpg#center "OTP according to Indonesia Minister of Communication and Information Technology")
[Tempo.co](https://bisnis.tempo.co/read/1630039/kebocoran-data-pribadi-terjadi-lagi-johnny-plate-masyarakat-harus-sering-ganti-password), quoting **Indonesia Minister of Communication and Information Technology**, Mr. **Johnny G Plate**:
> _"One time password itu harus selalu kita ganti sehingga kita bisa menjaga agar data kita tidak diterobos,"_.
Translated to English:
> _"We must always change our one-time password so that our data is not breached,"_.
Hmm... Excuse me! **OTP** or one-time password means a password that's only used once. After being used, the password is no longer valid. By nature, it changes itself and it's not us who decide its value.
> _I'm sure the minister doesn't really mean it. His intention was probably about regular passwords, wasn't it? right? Yeah?_ :worried:
Back to the topic of why I think changing passwords regularly is no longer relevant: because remembering the site or app we signed up for is already difficult, let alone having to change them regularly with random complex passwords.
In my personal opinion, by implementing the points I mentioned earlier, it's sufficient (for most people).
## Password Managers
The points I mentioned above will be very difficult to achieve without a **Password Manager**. Use an open-source password manager that can be freely audited by the public at any time.
There are many open-source password managers like [Bitwarden](https://bitwarden.com/), [KeepassXC](https://keepassxc.org/), [Padloc](https://padloc.app/), etc. If you have the infrastructure and capabilities to build and manage a _self-hosted server_ for your password manager, it would be better if you use its self-hosted version.
### Tips for Using a Password Manager
To follow my tips, you'll need:
- 2 email accounts, one of which is an email address **that has never been used** to register anywhere.
- The ability to remember at least 3 complex passwords that are different (**minimum 12 characters including numbers, symbols, uppercase and lowercase letters**).
So, let say I already have two email addresses:
1. `ditatompel@gmail.com`
2. `administrator@ditatompel.com`
I use the first email for every website registration that requires email verification (primary email). Remember and note down the password for logging in to this email **in your brain memory** (never write it anywhere, including a password manager).
The second email is **only** used for the recovery/reset password feature from the primary email. Don't tell anyone about this recovery email address except the provider of the primary email (in this case: Gmail).
> When you set up a recovery email address with your provider (such as Gmail), they will typically send notifications to that email if they detect suspicious activity on your account. Even if your primary email account has been compromised, you can still maintain control over your account by accessing it through the recovery email.
Register to your password manager provider using your primary email. Usually, the password manager will ask you to set up a **Master Password**. Use a different password from the passwords of the primary and recovery email. And, again: remember and note down the **Master Password** in your brain (never write it anywhere, including the password manager itself).
Don't forget to enable 2FA/OTP (if the provider offers this feature) for accessing these three important accounts (the primary email, the recovery email, and the password manager).
Use the password manager to generate and store all passwords for websites or applications you use **except** the primary email, the recovery email, and the master password of the password manager.
That way, you'll have different random passwords for each website or application you use without having to bother remembering them. I hope this article is helpful and adds insight.
> **NOTES**:
>
> - This tip won't be useful if your PC or device is already infected with malicious software like a keylogger.
> - Special note about email: If you use an email service provider like Yahoo! or Google, you may lose your email account if you never log in within a certain period of time. I wrote about this topic: ["_Why Inactive Email Accounts is Dangerous_"](https://insights.ditatompel.com/en/blog/2020/06/why-inactive-email-accounts-is-dangerous/). So, always make it a habit to log in to your email service provider at least once every 2 months.
Resources:
- Random data fed or [_salt (Cryptography)_](<https://en.wikipedia.org/wiki/Salt_(cryptography)>)
- [Dictionary Attack](https://en.wikipedia.org/wiki/Dictionary_attack)
- [Rainbow Table Attack](https://www.beyondidentity.com/glossary/rainbow-table-attack)

View file

@ -0,0 +1,102 @@
---
title: "Accessing Reddit Without VPN Using Libreddit"
description: "For individuals who face difficulties accessing Reddit in Indonesia due to ISP restrictions, using libreddit provides an alternative and easy means of accessing the platform without relying on a VPN."
summary: "For individuals who face difficulties accessing Reddit in Indonesia due to ISP restrictions, using libreddit provides an alternative and easy means of accessing the platform without relying on a VPN."
date: 2023-06-04T23:13:33+07:00
lastmod:
draft: false
noindex: false
featured: false
pinned: false
# comments: false
series:
# -
categories:
- TIL
- Privacy
tags:
- Reddit
- libreddit
images:
authors:
- vie
- jasmerah1966
---
Recently, many users in Indonesia have been experiencing difficulties in accessing Reddit due to Internet Service Provider (ISP) restrictions (read: "[New Stage of Internet Censorship in Indonesia: DPI & TCP Reset Attack]({{< ref "/blog/new-stage-of-internet-censorship-in-indonesia-dpi-tcp-reset-attack/index.md" >}})"). This issue has led to the development of various solutions that allow users to bypass these restrictions and access Reddit seamlessly.
One such solution is libreddit, a web-based application that enables users to access Reddit without the need for a Virtual Private Network (VPN). In this article, we will explore the features and benefits of using [libreddit](https://github.com/libreddit/libreddit) to access Reddit.
**Libreddit** is, in itself, an unofficial proxy interface for the website `reddit.com`, functioning as a connector between you and the `reddit.com` site.
## Libreddit _instances_
**Libreddit instances** is an engine that runs the `libreddit` program itself. This instance is usually operated by an individual, but there are also groups or organizations that operate a **Libreddit instance**.
Hereafter is a list of some instances you can use:
| URL | Location | Behind Cloudflare? | Comment |
| -------------------------------- | --------------- | ------------------ | -------- |
| https://reddit.moe.ngo | 🇮🇩 Indonesia | ✅ | |
| https://safereddit.com | 🇺🇸United States | | SFW only |
| https://lr.riverside.rocks | 🇺🇸United States | | |
| https://libreddit.privacy.com.de | 🇩🇪Germany | | |
For a more comprehensive and up-to-date list, please visit [https://github.com/libreddit/libreddit-instances/blob/master/instances.md](https://github.com/libreddit/libreddit-instances/blob/master/instances.md).
## How to use libreddit
Using `libreddit` is extremely easy; all you need is a browser, visit one of the instances above. Once you're on the front page of the instance you've chosen, the first thing you should do is select the subreddit you want to subscribe to.
This way, when you access the `libreddit` instance again in the future, the content that appears on the front page will be from the subreddits you have already subscribed to.
Here's how: search for the subreddit you want to subscribe to using the search bar. For example, [r/indonesia](https://safereddit.com/r/indonesia).
![Search on libreddit](libreddit-1.png#center)
After entering the subreddit page, click the **"Subscribe"** button. Then, posts from the subscribed subreddit will automatically appear on the front page.
## Advantages and Disadvantages
There are always pros and cons. I'd like to start with the disadvantages before moving on to the advantages.
### Disadvantages
The main disadvantage is that we can only browse or view content; we don't have the option to log in (and therefore can't interact with other users by leaving comments, upvoting, downvoting, etc.).
### Advantages
- No need for **VPN**
To access `libreddit`, you don't need to install or connect to a **VPN** if your ISP blocks Reddit. Simply use a browser and access the Libreddit instance I mentioned above.
- Ad-free
With libeddit, you can browse postings on Reddit without ads.
- Faster
From my experience, accessing Reddit using libreddit feels faster and more responsive.
- Privacy
**Libreddit** only uses "Cookies" to store your "Settings" and subscribed subreddits. These Cookies do not save any personal information about you.
- SFW (Safe For Work) or +NSFW (Not Safe For Work)
Some `libreddit` instances choose NOT to display NSFW content (**SFW** only), such as [safereddit.com](https://safereddit.com). So, you can feel more "safe" when browsing Reddit there.
## Tips for Using the **Privacy Redirect** Plugin
When searching online using search engines like Google.com, content from Reddit frequently appears in the results. Nevertheless, due to our internet service provider (ISP) blocking access to reddit.com, we are unable to directly access those links.
That's where the [_plugin browser "**Privacy Redirect**"_](https://github.com/SimonBrazell/privacy-redirect) comes in handy. Its job is to redirect (change) the original link to one that we've previously chosen.
For example, when a Google search result shows a link to _https://reddit.com/r/indonesia_, if we click on the link, the **Privacy Redirect** plugin will change it to our preferred Libreddit instance, such as _https://safereddit.com/r/indonesia_.
Currently, this plugin is available at [Firefox Add-Ons](https://addons.mozilla.org/en-US/firefox/addon/privacy-redirect/), [Chrome Web Store](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb), and [Microsoft Edge Add-ons](https://microsoftedge.microsoft.com/addons/detail/privacy-redirect/elnabkhcgpajchapppkhiaifkgikgihj).
To use it, simply install the plugin on your browser, enter "More Options" and input your preferred URL instance into "Reddit Instance".
![Privacy Redirect Plugin](privacy-redirect-plugin.png#center).
You can also easily toggle the redirect feature for each site using the `on` - `off` switch button as shown below:
![Privacy Redirect Plugin Switch](privact-redirect-plugin-swich-on-off.png#center).
## Alternative to Libreddit
In addition to **libreddit**, there is another alternative that works in a similar way (as a _proxy_) called [**teddit**](https://codeberg.org/teddit/teddit). From a visual standpoint, **libreddit** is more similar to the new Reddit design, while **teddit** appears to follow the older Reddit design (`old.reddit.com`).
From a programming language perspective, libreddit uses **Rust**, whereas teddit uses **NodeJS**.

View file

@ -0,0 +1,97 @@
---
title: "Devilzc0de Streaming Radio Amarok Script"
description: Since I'm the type of person who finds it difficult to work if there are lots of browser tabs open in the browser, I made a simple script so that devilzc0de radio can be listened to via Amarok.
summary: Since I'm the type of person who finds it difficult to work if there are lots of browser tabs open in the browser, I made a simple script so that devilzc0de radio can be listened to via Amarok.
date: 2011-12-29T03:14:32+07:00
lastmod:
draft: false
noindex: false
featured: false
pinned: false
series:
# -
categories:
# -
tags:
- Amarok
- Linux
images:
authors:
- ditatompel
---
_tested on_ :
- OS: **Arch Linux** Kernel `3.x` `x86_64`
- DE: **KDE** SC `4.7.4`
- Qt: `4.8.0`
- Source Code : `http://ls-la.ditatompel.crayoncreative.net/linux/devilzc0de_stream.tar.bz2`
![](dc-amarok2.png#center)
![](dc-amarok3.png#center)
![](dc-amarok4.png#center)
## List Radio Station
- ainstream
- Devilzc0de Radio
- Radio Bandung
- Prambors FM
- Delta FM
- Radio Surabaya
- Mercury 96FM
- Prambors FM
- Delta FM
- Radio Yogyakarta
- Redjo Buntung
- Jogjafamily
- Swaragama
- Female FM
- Prambors FM
- Radio Semarang
- Gajahmada FM
- TOP FM Bumiayu
- Female FM
- Prambos FM
- Radio Jakarta
- Delta FM
- Female FM
- Prambors FM
- Radio Lainnya
- Kaskus Radio
- Static Stream Crayon Networks
- Lagu Galauers
- Instrumental
- Latest Song Mix
## How to Install
You can install 2 methods, using **Amarok script manager** (_single user_) or manually (_all users_).
### Using Amarok Script Manager (_single user_)
1. Open Amarok
2. Enter **Settings** -> **Configure Amarok** -> **Script** -> **Manage Scripts**
3. Search with _keyword_ **Devilzc0de** -> **Install**
![](dc-amarok1.png#center)
### Manual (_all users_)
```bash
wget http://ls-la.ditatompel.crayoncreative.net/linux/devilzc0de_stream.tar.bz2
```
As `root` user, extract then copy the extracted directory to `/usr/share/apps/amarok/scripts/`.
## How to use
1. Go to the **internet** menu.
2. Select **devilzc0de Radio**.
3. Select the radio station you want to listen to.
Sorry, I haven't had time to create other audio player and desktop environments.
Questions & bugs report to `https://devilzc0de.org/forum/thread-11791.html`.

View file

@ -0,0 +1,119 @@
---
title: "Connect to the Internet Using ZTE AC2726i Smart Modem on Linux"
description: "Tutorial for connecting to the internet with the ZTE AC2726i Smart Fren modem (dual-mode USB modem) using wvdial."
summary: "Tutorial for connecting to the internet with the ZTE AC2726i Smart Fren modem (dual-mode USB modem) using wvdial."
date: 2012-09-08T19:40:46+07:00
lastmod:
draft: false
noindex: false
featured: false
pinned: false
# comments: false
series:
# -
categories:
# -
tags:
- BackTrack
- wvdial
- Linux
images:
authors:
- ditatompel
---
When this tutorial was created, I used the **BackTrack** distribution. And it should work on other **Linux** distributions too.
First, you need to [download `usb_modeswitch`](https://www.draisberghof.de/usb_modeswitch/#download). If you already have an internet connection (with **Wi-Fi**, for example), you can simply run the `wget` command:
```bash
wget https://www.draisberghof.de/usb_modeswitch/usb_modeswitch-1.0.2.tar.bz2
```
After the download process is complete, extract `usb_modeswitch-1.0.2.tar.bz2`, which you just downloaded.
```bash
tar -xjf usb_modeswitch-1.0.2.tar.bz2
```
Go to the `usb_modeswitch-1.0.2` directory and install:
```bash
cd usb_modeswitch-1.0.2; sudo make install
```
and you will get output similar like this:
```plain
[sudo] password for ditatompel:
mkdir -p /usr/sbin
install ./usb_modeswitch /usr/sbin
mkdir -p /etc
install ./usb_modeswitch.conf /etc
```
It can be seen that two files have been installed: `usb_modeswitch` and `usb_modeswitch.conf`. Edit `usb_modeswitch.conf`, which is located in the `/etc` directory.
```bash
sudo nano /etc/usb_modeswitch.conf
```
Add the following configuration, which is similar to **ZTE AC2710** (**EVDO**) modem configurations by **Wasim Baig**:
```plain
#########################################################
## ZTE AC2726i (EVDO)
DefaultVendor= 0x19d2
DefaultProduct= 0xfff5
TargetVendor= 0x19d2
TargetProduct= 0xfff1
MessageContent= "5553424312345678c00000008000069f010000000000000000000000000000"
```
Then, open the `wvdial` configuration in `/etc/wvdial.conf` and edit the configuration file:
> _\* I recommend always backing up your configuration before making changes._
```bash
sudo nano /etc/wvdial.conf
```
Add the following configuration:
```plain
[Dialer smart]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Modem Type = USB Modem
ISDN = 0
New PPPD = yes
Phone = #777
Modem = /dev/ttyUSB0
Username = smart
Password = smart
FlowControl = CRTSCTS
Carrier Check = No
Baud = 9600
```
The `usb_modeswitch` and `wvdial` configuration has been completed.
Run `usb_modeswitch` from the terminal to change the USB modem product from `fff5` to `fff1`.
```bash
usb_modeswitch
```
Then, the next step we need to do is detect the **product ID** of the modem we are using:
```bash
sudo modprobe usbserial vendor=0x19d2 product=0xfff1
```
Finally, run the `wvdial` command:
```bash
sudo wvdial smart
```
![wvdial Smart Fren](connect-internet-wvdial.png)

View file

@ -0,0 +1,122 @@
---
title: "PHP Email Advanced Validation (Format, MX Host, SMTP Mailbox)"
description: "A simple PHP script for validating email addresses using format, MX record, and SMTP mailbox checks."
summary: "A simple PHP script for validating email addresses using format, MX record, and SMTP mailbox checks."
date: 2012-10-14T20:02:21+07:00
lastmod:
draft: false
noindex: false
featured: false
pinned: false
series:
# -
categories:
- Programming
tags:
- PHP
images:
authors:
- ditatompel
---
It cannot be denied that on the internet, the existence of email is very important. With email, information can arrive very quickly even if the sender and recipient are on two different continents. Apart from that, email remains a popular choice for companies and developers to convey information to their customers.
This time, I'd like to share a simple PHP script to validate email addresses via writing format, MX record, and SMTP mailbox checks.
To validate an email address, we can do several things. Specifically, this involves checking the email's writing format, verifying the MX record on the domain you want to check, or even connecting to the destination SMTP server to determine the target user's whereabouts.
The source code is available for download at `http://go.webdatasolusindo.co.id/scripts/php/email-advanced-validation.php` or at `http://pastebin.com/yyjChgKF`.
## 1. Validate Email Format
The email format commonly used is as follows:
- `username@domain.com`
- `Username`: the intended recipient's name.
- `domain.com`: the domain name where the user is located.
However, this format validation has a weakness: we don't know whether the domain actually hosts a mail server. For instance, the email address `username@domaininvalid.com` will be considered valid, even though the domain does not exist. To ensure the domain's validity or nonexistence, we can check via the MX record.
## 2. Validate MX Records
The MX Record function typically delegates email for a domain/host to its destination mail server.
For example, running the command `dig wds.co.id MX +short`:
```plain
30 aspmx3.googlemail.com.
0 aspmx.l.google.com.
10 alt1.aspmx.l.google.com.
20 alt2.aspmx.l.google.com.
30 aspmx2.googlemail.com.
```
![dig record](php-email-dig_mxrecord.png#center)
This will display the MX Record for the domain `wds.co.id`.
By querying the MX record, it can be concluded that this domain allows email addresses. However, this validation has a weakness: we don't know whether the user on the domain actually exists.
For instance, the email address `fake.account@wds.co.id` will be considered valid even though the fake account does not exist on the targeted mail server.
To determine the user's actual existence, we can further develop this by connecting to the destination SMTP server.
## 3. Validate SMTP Mailbox
By connecting to the SMTP server, we can determine whether the user on the domain actually exists or not. For example, I use `telnet` to connect to port `25` (the default SMTP port) and execute SMTP commands.
```plain
dit@tompel ~ $ telnet aspmx3.googlemail.com 25
Trying 74.125.137.26...
Connected to aspmx3.googlemail.com.
Escape character is '^]'.
220 mx.google.com ESMTP c2si11647357yhk.33
HELO aspmx3.googlemail.com
250 mx.google.com at your service
MAIL FROM: <ditatompel@devilzc0de.org>
250 2.1.0 OK c2si11647357yhk.33
RCPT TO: <christian.dita@wds.co.id>
250 2.1.5 OK c2si11647357yhk.33
QUIT
221 2.0.0 closing connection c2si11647357yhk.33
Connection closed by foreign host.
dit@tompel ~ $ telnet aspmx3.googlemail.com 25
Trying 74.125.137.26...
Connected to aspmx3.googlemail.com.
Escape character is '^]'.
220 mx.google.com ESMTP w4si11351321yhd.42
HELO aspmx3.googlemail.com
250 mx.google.com at your service
MAIL FROM: <ditatompel@devilzc0de.org>
250 2.1.0 OK w4si11351321yhd.42
RCPT TO: <fake.account@wds.co.id>
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 http://support.google.com/mail/bin/answer.py?answer=6596 w4si11351321yhd.42
QUIT
221 2.0.0 closing connection w4si11351321yhd.42
Connection closed by foreign host.
```
![SMTP commands](php-email-telnetsmtp.png#center)
Pay attention to the initial telnet connection:
```plain
RCPT TO: <christian.dita@wds.co.id>
250 2.1.5 OK c2si11647357yhk.33
```
and the second telnet connection:
```plain
RCPT TO: <fake.account@wds.co.id>
550-5.1.1 The email account that you tried to reach does not exist. [ Blah blah blah... ]
```
On the first connection, it appears that the mail server wants to receive email for the intended recipient. On the second connection, the mail server does not want to receive email for the intended recipient.
Therefore, it can be concluded that the user `fake.account` in the `wds.co.id` domain does not actually exist.
Based on these three validations, I developed this basic concept of my **PHP E-Mail Advanced Validation** script.

View file

@ -0,0 +1,562 @@
---
title: "Compiling the Latest Stable Version of Nginx from Source Code"
description: "While Apache remains a popular choice for web servers, there are alternative options like Nginx that offer unique features and benefits. In this article, we'll explore how to compile the latest stable version of Nginx from its source code."
summary: "While Apache remains a popular choice for web servers, there are alternative options like Nginx that offer unique features and benefits. In this article, we'll explore how to compile the latest stable version of Nginx from its source code."
date: 2011-08-25T18:00:31+07:00
lastmod:
draft: false
noindex: false
# comments: false
nav_weight: 1000
series:
# - Tutorial
categories:
- SysAdmin
tags:
- Nginx
- Linux
- SysVinit
- Web Server
images:
authors:
- ditatompel
---
**Nginx**, a web server developed by **Igor Sysoev** in 2002, is a new alternative to **Apache**.
> _**NOTE**: This article was written in 2011, so you need to adapt in following this tutorial. Moreover, currently the majority of Linux distributions switched from `sysVinit` to `SystemD`._
Nginx (pronounced **"Engine X"**) is a lightweight web server and reverse proxy and email proxy with high performance, running on Windows, UNIX, GNU/Linux, Solaris, and BSD variants such as macOS.
## Why Nginx?
1. **Speed**: One core processor can efficiently handle thousands of connections, resulting in significantly reduced CPU load and memory consumption.
2. **Easy to use**: Configuration files are much easier to understand and modify than other web server configurations such as Apache. Just a few lines are enough to create a fairly complete `virtual host`.
3. **Plug-in system** (here referred to as "`modules`")
4. and most importantly, **Open Source** (BSD-like license)
Some examples of large websites that use Nginx either as a web server or as a reverse proxy to Apache include: **kaskus.us**, **indowebster.com**, **wordpress.com**, **sourceforge. net**, **github.com**, etc.
## Why compile?
In the web server installation process, several tools and parameters are required that we have to decide on during compilation, and several additional configurations that must be carried out and adapted to our system.
Well, this time we choose to download the source code of the application and install it manually rather than installing using the package manager. There are several reasons why people choose to install manually:
1. To get to know more about how the system (especially the web server) that we use works.
2. (Probably) not yet available in the repositories of the Linux distribution being used.
Besides that, repositories rarely offer to download and install Nginx using the package manager (`yum`, `apt`, or `yast`) for the latest version (except on rolling-release distributions such as Arch Linux). Most provide old versions that are not up to date.
## Nginx Compilation Process
Below is a capture screen video that I made previously. Perhaps it can help in the installation process. (It doesn't need to be exactly the same; the important thing is to know the process and how it works.)
{{< youtube AtJ5OBOj1gE >}}
### Download source code
First, let's download our web server from [http://nginx.org/download/nginx-1.0.5.tar.gz](http://nginx.org/download/nginx-1.0.5.tar.gz) (when I wrote this article, the latest stable version was 1.0.5).
```bash
wget http://nginx.org/download/nginx-1.0.5.tar.gz
```
After that, copy the source to `/usr/local/src/` and extract it.
```bash
sudo cp nginx-1.0.5.tar.gz /usr/local/src/
cd /usr/local/src/
sudo tar -xvzf nginx-1.0.5.tar.gz
```
**Notes:**
1. Before the installation process, it's better to check whether port 80 is being used or not. I'm using the BackTrack distro and by default Apache uses port 80 at startup. Run `/etc/init.d/apache2 stop` or `killall apache2`.
2. Nginx is a program created using the C programming language, so to be able to compile it, we first need to have tools such as the GNU Compiler Collection (GCC) on our computer. GCC is usually installed on most Linux distros.
To confirm, just run the command `gcc` (without quotes) in the terminal. If you get output "gcc: no input files", it means GCC is already installed on your computer. If not, you need to install it first.
OK, let's continue...
### ./configure dan make install
Go to the `nginx-1.0.5` directory under `/usr/local/src/` directory and start compiling.
```bash
cd nginx-1.0.5
./configure
```
By default, the **HTTP rewrite module** is automatically installed during the default Nginx installation. This module requires the **PCRE (Perl Compatible Regular Expression) library** because the **Rewrite** and **HTTP Core modules** of Nginx use PCRE as their _regular expression_ syntax.
Now it depends on our choice; if we:
1. require a rewrite module, we have to install PCRE first:
```bash
apt-get install libpcre3 libpcre3-dev
```
2. If we don't need it:
```bash
./configure --without-http_rewrite_module
```
Our choice fell on the first option because most of the sites we use needs the rewrite module. So after installing PCRE, we have to configure it again.
```bash
./configure
```
carry out the installation process:
```bash
make && make install
```
The default installation process that we did above will place the Nginx "workspace" in the `/usr/local/nginx` directory
### Creating a SysVinit Script for Nginx
Create a file with the name `nginx` in the `/etc/init.d/` directory:
```bash
nano /etc/init.d/nginx
```
Then copy and paste the shell script below, then save.
```bash
#! /bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the nginx web server
# Description: starts nginx using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/nginx/sbin/nginx
NAME=nginx
DESC="nginx daemon"
test -x $DAEMON || exit 0
# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
. /etc/default/nginx
fi
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
--exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
--exec $DAEMON
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile \
/usr/local/nginx/logs/nginx.pid --exec $DAEMON
sleep 1
start-stop-daemon --start --quiet --pidfile \
/usr/local/nginx/logs/nginx.pid --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
--exec $DAEMON
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
```
`chmod +x` so that the script can be executed.
```bash
chmod +x /etc/init.d/nginx
```
After this, we can **start**, **stop**, **restart**, or **reload** the Nginx process via the script. Let's try running Nginx:
```bash
/etc/init.d/nginx start
```
Then, we should get a welcome message "Welcome to nginx!" when accessing `localhost` from your browser.
## Installation and configuration of PHP FastCGI (spawn-fcgi) with Nginx
Install `spawn-fcgi`.
```bash
apt-get install php5-cgi spawn-fcgi
```
After the installation process via the package manager is complete, create a file named `php-fastcgi` in the `/etc/init.d/` directory:
```bash
nano /etc/init.d/php-fastcgi
```
Copy and paste the shell init script below:
```bash
#!/bin/bash
BIND=127.0.0.1:9000
USER=www-data
PHP_FCGI_CHILDREN=15
PHP_FCGI_MAX_REQUESTS=1000
PHP_CGI=/usr/bin/php-cgi
PHP_CGI_NAME=`basename $PHP_CGI`
PHP_CGI_ARGS="- USER=$USER PATH=/usr/bin PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND"
RETVAL=0
start() {
echo -n "Starting PHP FastCGI: "
start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
RETVAL=$?
echo "$PHP_CGI_NAME."
}
stop() {
echo -n "Stopping PHP FastCGI: "
killall -q -w -u $USER $PHP_CGI
RETVAL=$?
echo "$PHP_CGI_NAME."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: php-fastcgi {start|stop|restart}"
exit 1
;;
esac
exit $RETVAL
```
Don't forget to `chmod +x` so that the script can be executed.
```bash
chmod +x /etc/init.d/php-fastcgi
```
Then, before running `php-fastcgi`, we first build the website structure that we will use. (I chose the `/var/www/nginx` directory.)
```bash
mkdir -p /var/www/nginx; cd nginx
```
Create a file with the name `info.php` containing `phpinfo();` (just to test whether PHP is running or not):
```bash
echo "<?php phpinfo(); ?>" > info.php
```
Then, edit the Nginx configuration to suit the structure of the website we are building.
```bash
nano /usr/local/nginx/conf/nginx.conf
```
Because our root public HTML is in `/var/www/nginx`, then the configuration is as follows:
```nginx
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /var/www/nginx;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/nginx$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443;
# server_name localhost;
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
```
Note that I changed the `root` and `fastcgi_param SCRIPT_FILENAME` configuration (video minute 7:00).
To test whether the configuration we created is correct, we can run the following command:
```bash
/usr/local/nginx/sbin/nginx -t
```
If the syntax and test are successful, then restart Nginx using the init file that we created earlier.
```bash
/etc/init.d/nginx restart
```
Test accessing the `info.php` file via the browser at `http://localhost/info.php`.
From there, we can determine whether Nginx can run and connect to PHP-FastCGI or not.
## Security Issue
In terms of computer and software security, we know that no system is perfect and free from bugs.
### Nginx “_no input file specified”_ PHP fast-cgi 0day Exploit
After Nginx and PHP CGI are running, try accessing http://localhost/whatever.php
If the browser displays "_No input file specified_", our configuration remains vulnerable and is not yet suitable for use.
**Exploit** : Create `anything.gif` file using **GIMP**. In the comment box, fill in the PHP _script_ `<?php phpinfo(); ?>` and place it in the nginx server root directory (in this article `/var/www/nginx/anything.gif`).
![Nginx 0day](nginx-0day.png#center)
Normally, if we access it from the browser `http://localhost/anything.gif` it will appear as a normal `.gif` image. But try accessing the URL from `http://localhost/anything.gif/whatever.php` then the results are amazing:
![Nginx 0day Exploit](nginx-0day-exploit.png#center)
The `.gif` file is executed as a PHP file (remember the _comment_ on the `.gif` file `<?php phpinfo(); ?>`).
Of course `http://localhost/anything.gif/whatever.php` doesn't actually exist. But every request that ends with `.php` will be **EXECUTED** as a PHP script by Nginx via the `cgi.fix_pathinfo` feature so that Nginx executes the `.gif` file as a PHP script!
How to overcome :
1. Change `cgi.fix_pathinfo=1` to `cgi.fix_pathinfo=0` in `php.ini`
2. Edit `/usr/local/nginx/conf/nginx.conf` and add the following sctipt between _block_ `server { }`
```nginx
error_page 400 402 403 404 /40x.html;
location = /40x.html {
root html;
}
```
## Modules
### Nginx Configure Module Options
During the configuration process, some modules will be enabled by default, and some need to be explicitly enabled.
#### Enabled by Default
The following modules are **enabled by default** when the `./configure` command is executed. To disable a module, add the commands below:
`--without-http_charset_module`: Disables _module_ _Charset_ for _re-encoding_ web pages.
`--without-http_gzip_module`: Disables _module_ **Gzip** compression.
`--without-http_ssi_module`: Disables **Server Side Include module**.
`--without-http_userid_module`: Disables the _User ID module_ which provides user identification using cookies.
`--without-http_access_module`: Disables the access restriction _module_ which allows us to configure access for a specific **IP range**. for example: `deny 192.168.1.1/24`.
`--without-http_auth_basic_module`: Disables **Basic Authentication module**. (like **Auth Basic Apache**)
`--without-http_autoindex_module`: Disables **Automatic Index module**.
`--without-http_geo_module`: Disables the _module_ that allows us to define _variables_ according to a specific **IP range**.
`--without-http_map_module`: This module allows us to classify a value into different values, storing the results in the form of a _variable_.
`--without-http_referer_module`: This module allows to block access based on the `http referer` _header_.
`--without-http_rewrite_module`: Disables the **Rewrite** module.
`--without-http_proxy_module`: Disables **HTTP proxy module** for transfer requests to another server (_reverse proxy_).
`--without-http_fastcgi_module`: Disables the _module_ for interaction with the **FastCGI** process.
`--without-http_memcached_module`: Disables the _module_ for interaction with the _memcache_ daemon.
`--without-http_limit_zone_module`: This module allows to limit the number of connections for a specific address / directory.
`--without-http_limit_req_module`: Disables **module limit requests** which allows us to limit the number of _requests per user_.
`--without-http_empty_gif_module`: Returns a 1px x 1px transparent `.gif` image. (very useful for web designers)
`--without-http_browser_module`: Disables the module that allows us to read the **User Agent** _string_.
`--without-http_upstream_ip_hash_module`: Disables the **IP-hash** module for load-balancing to the _upstream_ server.
#### Disabled by Default
The following modules are disabled by default. To enable these modules, add the commands below:
`--with-http_ssl_module`: Enables **SSL module** for websites using the `https://` protocol.
`--with-http_realip_module`: Enables the _module_ to read the actual IP address of a request (usually obtained from the **HTTP header** _trusted proxy_).
`--with-http_addition_module`: Enables _module_ which allows us to add data to website pages.
`--with-http_xslt_module`: Enables _module_ for XSL to XML transformation. Note: Need to install `libxml2` and `libxslt` _library_.
`--with-http_image_filter_module`: Enables the _module_ that allows us to modify images. Note: Need to install `libgd` _library_ for this _module_.
`--with-http_sub_module`: Enables the _module_ to perform _replace_ text in a web page.
`--with-http_dav_module`: Enables the **WebDAV** feature
`--with-http_flv_module`: Enables a special _module_ to _handle_ _flash video files_ (`.flv`).
`--with-http_gzip_static_module`: Enables **module GZIP static compression**.
`--with-http_random_index_module`: Enables the _module_ to randomly select a file as the _index file_ in a directory.
`--with-http_secure_link_module`: Enables the _module_ to check URL requests with the required _security token_. (Also great for anticipating **CSRF**)
`--with-http_stub_status_module`: Enables a _module_ that _generates_ server statistics and web server process information.
#### Miscellaneous options
`--with-ipv6`: Enable IPv6 support
As we can see, configuring a web server is quite easy. In general, we only need to add an **SSL module** for serving HTTPS content and "Real IP" to retrieve the visitor's IP address if we use a proxy or run Nginx as a backend server with another web server.
Example of configuration with all modules:
```bash
./configure --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module
```
references:
- [http://wiki.nginx.org/](http://wiki.nginx.org/)
- [http://markmail.org/browse/ru.sysoev.nginx](http://markmail.org/browse/ru.sysoev.nginx)
- [http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/](http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/)

View file

@ -0,0 +1,165 @@
---
title: "Implementing Firewall Protection via Iptables Port Knocking"
description: "Strengthening server security by leveraging port knocking techniques in conjunction with iptables firewall functionality."
summary: "Strengthening server security by leveraging port knocking techniques in conjunction with iptables firewall functionality."
date: 2013-07-01T22:16:19+07:00
lastmod:
draft: false
noindex: false
# comments: false
nav_weight: 1000
series:
# - Tutorial
categories:
- SysAdmin
- Security
tags:
- iptables
- Port Knocking
- Linux
images:
authors:
- ditatompel
---
This time, I'd like to share some tips on how to enhance server security by utilizing the technique of _port knocking_. Port knocking is a method for opening a specific port by sending packets to predetermined ports beforehand.
> _Q: What's the purpose?_
A: The objective is to thwart attacks from penetration testers who conduct port scanning to identify services that might be exploitable by them. If the penetration tester fails to knock on the previously designated ports in sequence, the protected port will remain inaccessible.
> _Q: Can you elaborate?_
A: For instance, suppose we have an SSH service listening on port 22, while the penetration tester has a 0-day remote root exploit for OpenSSH. Therefore, our server's security is at risk due to the open port 22. By employing the technique of port knocking, only those who know which ports to "hit" first can
unlock and access port 22.
To clarify, I'll provide an example from my previous thread about **Lawang Sewu CTF** (`http://devilzc0de.org/forum/thread-20071.html`). The second challenge involves port knocking.
This port knocking technique can be configured using the iptables firewall, which is typically already possessed by the Linux kernel on most Linux distributions.
On this occasion, I'll share how to configure port knocking with iptables.
> **Disclaimer**: By following this tutorial, the author have no responsibility for any errors or loss of remote access to the server.
VIDEO TUTORIAL : [http://youtu.be/0zFQocf7C_0](http://youtu.be/0zFQocf7C_0).
What you need for this tutorial:
- Server & Client with Linux OS (in this tutorial, I'm using CentOS)
- `iptables` (server firewall)
- `nmap` (for scanning and knocking ports from the client)
- Basic knowledge of `iptables`
**Case Study:**
I have a server with IP address `192.168.0.100`, and I'm using SSH for remote management of that server. The default SSH port for remote access is `22`. I want to close port `22` and only make it available when needed.
This is where we use the technique of port knocking, which I've already set up so that users need to send a TCP packet to, for example, ports `1111`, then `2222`, then `3333`, and finally `4444` before port `22` (SSH) becomes accessible.
- Server IP: `192.168.0.100`.
- OS: **CentOS**.
- SSH Port: `22`.
- **Port Knocking** Scheme: TCP packet to ports `1111` => `2222` => `3333` => `4444` => Port `22` becomes accessible.
By default, the CentOS server's firewall has already opened port 22 for SSH.
![Port 22 open](pk-01.png#center)
So we need to reconfigure the `iptables` firewall. We can use the command `iptables-save > iptables.rules` to perform a dump/back up of the firewall rules.
Let's take a look at the new firewall configuration that we just dumped, which is roughly as follows (for CentOS):
```plain
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
```
![iptables dump config](pk-02.png#center)
Note the following firewall rules:
```plain
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
```
It appears that `iptables` allows access through port 22.
Let's create an `iptables` rule according to our wishes in this case study, namely we want to close port `22` and only make it accessible when ports `1111`, `2222`, `3333`, and `4444` receive a sequential TCP packet.
Copy the previous `iptables.rules` file to `iptables-new.rules`, then edit:
```bash
cp iptables.rules iptables-new.rules
vi iptables-new.rules
```
and edit it as shown below:
![iptables port knocking rules](pk-03.png#center)
In other words, I opened port `80`, then added a new firewall rule that dynamically opens port `22` for 15 seconds if ports `1111`, `2222`, `3333`, and `4444` receive sequential TCP packets within a 5-second timeframe.
After it's deemed okay, we restore the new firewall configuration using `iptables-restore`, then restart the iptables service.
```bash
iptables-restore < iptables-new.rules
service iptables save
service iptables restart
```
Then, to ensure the new rules are running, use the command:
```bash
iptables -L -n
```
![iptables rules list](pk-04.png#center)
Now that's done, let's try checking port `22` on our server from our computer using `nmap`, and it will show that the port is closed by the firewall.
```bash
nmap -Pn 192.168.0.100 -p22
```
![nmap port 22](pk-05.png#center)
After that, we'll create a simple bash script to perform port knocking.
```bash
#!/bin/bash
HOST=$1
shift
for ARG in "$@"
do
nmap -PN --host_timeout 201 --max-retries 0 -p $ARG $HOST
done
```
Save it as `knock.sh` and then run `chmod +x` so that the script can be executed.
Usage:
```bash
# ./knock.sh [ip server] [list port]
# Example:
./knock.sh 192.168.0.100 1111 2222 3333 4444
```
By knocking on ports `1111`, `2222`, `3333`, and `4444` in sequence, the port `22` we specified in the firewall rules will become accessible. This way, you can establish an SSH connection to the server.
![nmap port knocking](pk-06.png#center)
That's it for this port knocking tutorial.
Feel free to develop it further on your own with creativity, using a combination of protocols such as **TCP**, **UDP**, or even **ICMP**.
Reference:
- [http://en.wikipedia.org/wiki/Port_knocking](http://en.wikipedia.org/wiki/Port_knocking)
- [http://www.faqs.org/docs/iptables/index.html](http://www.faqs.org/docs/iptables/index.html)
- [https://wiki.archlinux.org/index.php/Port_Knocking](https://wiki.archlinux.org/index.php/Port_Knocking)
- Additional resource by **@od3yz**: [http://www.overflow.web.id/source/Metode-Port-Knocking-dengan-Iptables.pdf](http://www.overflow.web.id/source/Metode-Port-Knocking-dengan-Iptables.pdf)

View file

@ -0,0 +1,84 @@
---
title: "Installing PHP, Apache, MySQL, and phpMyAdmin on Arch Linux"
description: "A step-by-step guide to installing PHP, Apache, MySQL, and phpMyAdmin on Arch Linux."
summary: "A step-by-step guide to installing PHP, Apache, MySQL, and phpMyAdmin on Arch Linux."
date: 2012-02-18T05:01:30+07:00
lastmod:
draft: false
noindex: false
# comments: false
nav_weight: 1000
series:
# - Tutorial
categories:
- SysAdmin
tags:
- Linux
- MySQL
- Apache
- PHP
images:
authors:
- ditatompel
---
Why Arch Linux? Because I'm comfortable using Arch, and with its package manager, we can easily install the latest and most up-to-date kernel and software.
**Video (in Indonesian):**
{{< youtube zr7TVU7SZUs >}}
1. First, we ensure that our system is up to date by running:
```bash
pacman -Syu
```
2. Next, we install the necessary packages using:
```bash
pacman -S php apache php-mcrypt phpmyadmin mysql
```
3. We then navigate to the `/etc/webapps/phpmyadmin` directory and copy the `phpmyadmin` configuration file to `/etc/httpd/conf/extra`:
```bash
cp /etc/webapps/phpmyadmin/apache.example.conf /etc/httpd/conf/extra/httpd-phpmyadmin.conf
```
4. We include the configuration in the main `httpd.conf` file located in the `/etc/httpd/conf` directory by adding:
```apache
# phpmyadmin configuration
Include conf/extra/httpd-phpmyadmin.conf
```
![Apache Config PHPMyAdmin](phpmyadmin-include.png#center)
Then, we can access `localhost` and `phpmyadmin` in the browser.
6. If there is a forbidden message in **phpmyadmin**, we need to add the `DirectoryIndex index.html index.php` configuration to `/etc/httpd/conf/extra/httpd-phpmyadmin.conf`, then restart the http server.
![DirectoryIndex Apache](directoryIndex.png#center)
7. If **PhpMyAdmin** can be accessed, but there is still an error message "The mysqli extension is missing." or "The mcrypt extension is missing"; We need to enable the extension in `php.ini` by removing the semicolon (`;`) from the required extension.
![PHP Extension](extension.png#center)
```ini
extension=mcrypt.so
extension=mysqli.so
extension=mysql.so
```
Then, we can restart the http server again.
FYI: On Arch Linux, by default `httpd` runs as user `http` and group `http`. To make it more comfortable and avoid error messages on certain CMS installations, we need to change the permissions and owner of the `/srv/http` folder (where the `public_html` folder is located) using:
```bash
chown -R http:http /srv/http
```
The installation process for Apache, PHP, MySQL, and PhpMyAdmin is now complete.
For now, this concludes the basics.

View file

@ -0,0 +1,108 @@
---
title: "PHPMyAdmin Configuration for Multi Database Server"
description: How to configure the PHPMyAdmin application so that it can be used to manage multiple MySQL database servers.
summary: How to configure the PHPMyAdmin application so that it can be used to manage multiple MySQL database servers.
date: 2012-08-15T17:49:16+07:00
lastmod:
draft: false
noindex: false
# comments: false
nav_weight: 1000
series:
# - Tutorial
categories:
- SysAdmin
tags:
- PHP
- MySQL
images:
authors:
- ditatompel
---
On this occasion I would like to share how to configure the **PHPMyAdmin** application so that it can be used to manage **multiple MySQL database servers** (remotely).
When writing this article, the author used PHPMyAdmin Version `3.5.2.1` with Apache Web Server running on Linux OS. Meanwhile, the remote MySQL database server uses version `5.x`. Previously, the author assumed that you were able to run PHPMyAdmin on your computer.
## Remote MySQL Server
On the remote MySQL server, create a new database user that we will use to access the server from our PC or personal computer.
First, log in to MySQL and create a new user:
```sql
CREATE USER 'user_name'@'ip_address' IDENTIFIED BY 'password';
```
**Where**:
- `user_name` is the database username that we use to log in to the database server.
- `ip_address` is the IP address or hostname where PHPMyAdmin is installed.
- `password` is the password to log in to the database server.
After that, grant the required permissions to the user with the **GRANT** command:
```sql
GRANT ALL PRIVILEGES ON *.* TO 'user_name'@'ip_address';
```
![MySQL GRANT](phpmyadmin1.png#center)
**Where**:
- `ALL PRIVILEGES` means all permissions that the user has, except for the **GRANT** option to other users.
- `*.*` means all databases and tables. The first asterisk represents the database name, and the second asterisk represents the table in the database.
- `'user_name'@'ip_address'` is the username that we created previously.
For example, if you only want **SELECT** permission, and **UPDATE** permissions for the `tbl_transaction` table in the `db_website` database for user `finance` with IP address `192.169.1.1`, use:
```sql
GRANT SELECT, UPDATE ON db_website.tbl_transaction TO 'finance'@'192.169.1.1';
```
Then, finally, don't forget to **FLUSH PRIVILEGES**.
```sql
FLUSH PRIVILEGES;
```
## PHPMyAdmin Client
Find where the PHPMyAdmin application is located. In this tutorial, the location is `/usr/share/webapps/phpmyadmin`. Edit the config.inc.php file in that directory and add the following configuration:
```php
$i++;
$cfg['Servers'][$i]['verbose'] = 'MRTG IP 169.1/28';
$cfg['Servers'][$i]['host'] = '192.168.1.5';
$cfg['Servers'][$i]['port'] = '3306';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['auth_type'] = 'cookie';
```
![PHPMyAdmin `config.inc.php`](phpmyadmin2.png#center)
**Where :**
- `verbose` is the server name that will appear in PHPMyAdmin.
- `host` is the IP address or domain name of the remote MySQL database server.
- `port` is the port number of the remote MySQL database server (default `3306`).
- `connect_type` is the connection type used. There are two options: `socket` and `tcp`. We use `tcp` because the MySQL server is not on the same server as the PHPMyAdmin server that is currently running.
- `extension` is the PHP MySQL extension used for the above connection.
- `auth_type` is the authentication mode used for login.
After that, try opening the PHPMyAdmin page in a web browser. Then additional options will appear on the login page, as follows:
![PMA Login Page](phpmyadmin3.png#center)
Then, simply log in with your username and password according to the server choice.
With this feature, you can perform or utilize synchronization from a remote server to a local server or vice versa:
![PHPMyAdmin View](phpmyadmin4.png#center)
Or monitor remote databases from your personal computer, even though PHPMyAdmin is not installed on the remote MySQL server.
![MySQL Process PHPMyAdmin](phpmyadmin5.png)
Hope it's useful.

View file

@ -0,0 +1,107 @@
---
title: "Reading Binaries Manually"
description: "How to read a set of numbers 0 and 1 (Binary) into decimal. Then how to use the decimal number to translate it into text (ASCII) using an ASII table"
summary: "How to read a set of numbers 0 and 1 (Binary) into decimal. Then how to use the decimal number to translate it into text (ASCII) using an ASII table"
# linkTitle:
date: 2012-01-08T04:29:52+07:00
lastmod:
draft: false
noindex: false
nav_weight: 1000
series:
categories:
- TIL
tags:
- Binary
images:
authors:
- ditatompel
- jasmerah1966
---
I'd like to share with you a tutorial on reading binary numbers manually, which can be useful for those interested in computer science. This article is based on information gathered from various sources, including **@Capsoel**'s work in **X-Code Magazine issue 6** and **@ditatompel** from **devilzc0de**.
## What are Binary Numbers?
Binary numbers are a fundamental number system used to represent data as a sequence of 0s and 1s. Each digit represents a **power of 2**, allowing for a very efficient representation of large amounts of information. Binary is widely used in computer science, engineering, and various scientific fields.
At first glance, the series of 0s and 1s below may seem puzzling:
```
01000100011001010111011001101001011011000111101001100011001100000110010001100101
```
However, this is actually a binary code. In this article, we will explore how to read these numbers and translate them into decimal and eventually text (ASCII) using the ASCII table.
## Translating Binary to Decimal
To illustrate the process, let's consider an example:
```
10101
```
Imagine five empty slots (`_ _ _ _ _`) that represent the binary code. To read the binary code, start from **right to left**. Each slot has a specific value:
- Slot 1: 1
- Slot 2: 2
- Slot 3: 4
- Slot 4: 8
- Slot 5: 16
- and so on until the 8th slot.
Assigning a 0 or 1 to each slot determines the value of that slot.
For instance, if the first slot is 0 and the second slot is 1 (`_ _ _ 1 0`), the decimal number would be `2` because:
```plain
0 * 1 = 0
1 * 2 = 2
========= +
2
```
Another example, if the first slot is 1, the second slot is 0, and the third slot is 1 (`_ _ 1 0 1`), the decimal number would be `5` because:
```plain
1 * 1 = 1
0 * 2 = 0
1 * 4 = 4
========= +
5
```
## Translating Binary to ASCII
Now let's consider a longer binary code:
```
01000100011001010111011001101001011011000111101001100011001100000110010001100101
```
To translate this into decimal and eventually text, split the binary code into eight-digit groups (octets):
```
01000100 01100101 01110110 01101001 01101100 01111010 01100011 00110000 01100100 01100101
```
Then convert each group to a decimal number:
- `01000100` = 68
- `01100101` = 101
- ...
## Translating Decimal to ASCII
To translate the decimal numbers into text, you can use an ASCII table or a Windows-based application like Notepad. The ASCII table is shown below:
![ASCII table](ascii-table.png#center "ASCII table")
Alternatively, on Windows, hold the `<ALT>` key and press the corresponding decimal number to display the ASCII character. For example:
- `68` = `D`
- `101` = `e`
Try experimenting with different combinations to see how they translate!
I hope this revised article is helpful in understanding how to read binary numbers manually and translating them into text.

View file

@ -0,0 +1,199 @@
---
title: "Creating a virtualization lab on a local network with VirtualBox (2012)"
description: "This comprehensive guide leverages VirtualBox to build a virtualization lab on a local network, offering a flexible and cost-effective testing environment."
summary: "This comprehensive guide leverages VirtualBox to build a virtualization lab on a local network, offering a flexible and cost-effective testing environment."
# linkTitle:
date: 2012-12-21T20:40:14+07:00
lastmod:
draft: false
noindex: false
# comments: false
nav_weight: 1000
series:
# - Tutorial
categories:
- SysAdmin
tags:
- VirtualBox
- Linux
- MySQL
images:
authors:
- ditatompel
---
Recently, several friends have asked and are interested in learning to build servers. Most of them think that to learn to build or maintain a server, you need a Virtual Private Server (VPS) or even a dedicated server. Is that true? Although the price for VPS for some students is considered quite high, let alone a dedicated server.
Actually, if we just want to learn, we don't have to rent a VPS; instead, we can use something called virtualization (It's called learning, so you don't need a public IP that can be accessed by anyone; that's why we use a local network).
There are many ways to do this virtualization: **OpenVZ**, **VirtualBox**, **Xen**, **VMware**, etc. - from _para-virtualization_ to _full-virtualization_, from community (free) to enterprise (paid) versions. Each has its advantages and disadvantages (although I don't want to debate this issue).
This time, I used VirtualBox because many users already use it on their personal computers. Before continuing, I will first inform you of the situation and conditions at the time this guide was created.
- Subnet: `/24`
- Gateway: `192.168.0.2`
- Host OS: IP=`192.168.0.242`, OS=`Linux`
I want to create two virtual servers - one for a database server (MySQL server) and another server for something I haven't thought of yet. ;p
So what's needed:
- VirtualBox with `vboxnetfit` module
- ISO CentOS 6.x netinstall
- Internet connection
Video:
{{< youtube r5s8lBDNBXI >}}
## Part 1: Setting Guest Hosts (virtual servers)
Firstly, we definitely need VirtualBox. Please download it if you don't have it already. Then, install the `vboxnetfit` module for bridged adapter to virtual server. You may also need the `vboxdrv` module (optional for running a custom kernel). Activate it by issuing `modprobe [module_name]` command.
Next, let's run VirtualBox and create a virtual host. To do this, click the New icon at the top left, then enter the name and OS information used. For example:
- **Name** : CentOS Server Example III
- **Type** : Linux
- **Version** : RedHat (32/64 according to Host CPU)
Then press the Next button.
![Add New VirtualBox Host](feature-virtual-lab-jar-lokal-01.png#center)
Next, determine the **RAM** capacity that will be used by the virtual server, just give it **512MB**, then press the next button again.
![VirtualBox Set Guest RAM](virtual-lab-jar-lokal-02.png#center)
Next, create a virtual HDD, select option 2 **"Create a virtual hard drive now"** then press next.
![VirtualBox Set Guest Virtual HDD](virtual-lab-jar-lokal-03.png#center)
After that, another option appears for the hard drive type. If you don't want to move to another virtualization later, just select default **VDI**. But this time I chose **QEMU**.
![VirtualBox Set Guest Virtual HDD Type](virtual-lab-jar-lokal-04.png#center)
Later on the left there will be a list of Virtual Guests that have been created. Right click on the menu we just created and select **"Settings"**.
In the **Storage** => **Controller IDE** menu, select the image file used. I'm using **ISO CentOS 6.2 Netinstall 64-bit**.
![VirtualBox Set Guest OS](virtual-lab-jar-lokal-05.png#center)
Then in the **Network** menu -> **Adapter 1**, change **Attached to** from **NAT** to **Bridged Adapter**. The name corresponds to the interface being used (in my case: `eth0`).
![VirtualBox Set Bridged Adapter](virtual-lab-jar-lokal-06.png#center)
Click **Ok**, then Start **Virtual Guest**.
So, the installation process is the same as installing a regular OS.
![Linux install method](virtual-lab-jar-lokal-07.png#center)
What you need to pay attention to is: Use a static IP/_Static DHCP_ address from the router, not dynamic. Because if our IP is dynamic it will be difficult to remote, especially the SSH fingerprint problem.
![Linux install IP setting](virtual-lab-jar-lokal-08.png#center)
This time I gave the IP `192.168.0.152`, Gateway `192.168.0.2` and use Google's DNS server (`8.8.8.8`).
Then fill in the **CentOS** image URL, I used `mirror.nus.edu.sg`, please change it via `kambing.ui.ac.id` / whatever that is. What is clear is that it suits the architecture you are using. For example (`http://kambing.ui.ac.id/centos/6.3/os/x86_64` for those using **64-bit**).
![Linux setup URL](virtual-lab-jar-lokal-09.png#center)
Then click ok and wait for the installation process finished; then you will be asked to _reboot_ the OS.
**Reboot**/**Poweroff** the virtual guest. We edit the **primary boot** from **CD-ROM** to **Hard Disk**. The method:
**Setting** -> **System** -> **Motherboard** -> **Boot Order** -> Raise the **Hard Disk** menu to the first position / uncheck **Floppy** and **CD/DVD-ROM**.
![VirtualBox Boot Order](virtual-lab-jar-lokal-10.png#center)
Try running Virtual Guest again. You can use **CLI** so that the virtual host can run in the background:
- display the Virtual Guest list with the command: `VBoxManage list vms`
![VBoxManage list vms](virtual-lab-jar-lokal-11.png#center)
- run the following command to run the virtual guest in the background: `VBoxManage startvm "virtual machine name" --type=headless`.
For example:
```bash
VBoxManage startvm "CentOS Server Example III" --type=headless
```
Once it's running, try `ping` the virtual guest IP that we created earlier (`192.168.0.152`), wait for it to come up and log in via **SSH**.
```bash
ssh root@192.168.0.152
```
From there you can set the hostname, update software, etc.
## Part 2: Install another Guest Host
Repeat **Part 1** to create another _Virtual Guest_ so that we have two _virtual hosts_, and run it simultaneously with the headless option. Give this second virtual guest the IP `192.168.0.151`. For example, this time, we will use the second virtual guest as a database server.
In this second virtual guest, install MySQL server:
```bash
yum install mysql mysql-devel mysql-server
```
Start MySQL server
```bash
service mysqld start
```
Setup the MySQL server by running the command `/usr/bin/mysql_secure_installation`. This will prompt an interactive sequence of questions to secure the MySQL server installation.
Then, log in to the MySQL server as the `root` user to create a new user and database.
```bash
mysql -h localhost -u root -p
```
You will be asked to enter the MySQL password for the `root` user. Once logged in, create a new user:
```bash
CREATE USER 'ditatompel'@'192.168.0.%' IDENTIFIED BY 'password';
```
Where:
- `ditatompel` is **username**
- `192.168.0.%` represents the hostname/IP from which it makes remote connections to the MySQL server (note: this is equivalent to `192.168.0.0/24`)
- `password` is the password used
```sql
CREATE DATABASE IF NOT EXISTS db_testing;
```
Where `db_testing` is the name of the database that we will use later.
```sql
GRANT SELECT, INSERT, UPDATE, DELETE ON db_testing.* TO 'ditatompel'@'192.168.0.%';
```
Where `SELECT`, `INSERT`, `UPDATE`, and `DELETE` are user permissions granted from host `192.168.0.%` on all tables in the `db_testing` database (`db_testing`.\*). Don't forget to execute **FLUSH PRIVILEGES** afterwards.
```sql
FLUSH PRIVILEGES;
```
Also ensure that the default **MySQL** port (3306) is not blocked by your _firewall_.
![iptables](virtual-lab-jar-lokal-12.png#center)
Afterward, try connecting to the MySQL server from the first virtual guest or from our PC using the following command:
```bash
mysql -h 192.168.0.151 -u ditatompel -p
```
Where `192.168.0.151` is the IP address of the MySQL server and `ditatompel` is the user that we created on the MySQL server previously.
![iptables](virtual-lab-jar-lokal-13.png#center)
> **Q**: If I want to create 5 virtual guests and my laptop/PC RAM is only 1GB, that's not possible, then what?
**A**: Then use/bring a friend's laptop home, plug it into the same network, and run VirtualBox on that machine. Do the steps above to set up the virtual environment. If you have multiple laptops and can dedicate one laptop per three virtual guests, you could potentially create 12 virtual guests.
So, once everything is connected and communicating, that's essentially it. You can also conduct testing to learn about port knocking, firewall configuration, intrusion detection systems (IDS)/intrusion prevention systems (**IPS**), load balancing, and clustering. However, the results will still be far from optimal.

View file

@ -0,0 +1,246 @@
---
title: "SSH Client - Server (Security & Simplicity)"
description: Hardening SSH access by disabling root SSH access, change the default port, and utilize public and private keys.
summary: Hardening SSH access by disabling root SSH access, change the default port, and utilize public and private keys.
# linkTitle:
date: 2012-05-17T17:09:21+07:00
lastmod:
draft: false
noindex: false
# comments: false
nav_weight: 1000
series:
# - Tutorial
categories:
- SysAdmin
- Security
tags:
- Linux
- SSH
images:
authors:
- ditatompel
---
For System Administrators, using **SSH** instead of **Telnet** is likely a daily routine when accessing Linux/Unix-based systems. Although the password transmitted to the server has been encrypted and no longer appears as plaintext, the default installation of OpenSSH is considered somewhat insecure.
This time, I'd like to share some common tricks for tightening up SSH access. This includes disabling SSH access for the root user, utilizing public and private keys, and even modifying the default port. Additionally, I'll be sharing a few tips to make server management easier and simpler.
To participate in this discussion, you should have:
- A client PC with Linux running KDE 4.8.
- A remote SSH server (Remote PC) with an IP address of 202.150.169.245.
- Basic understanding of Linux command-line interfaces, such as `chmod`, `ssh`, `groupadd`, and `useradd`.
- The ability to use text editors like `vi`/`vim`/`nano`/`pico`, etc.
## Disabling Root Access via SSH
The "root" user is undoubtedly present on Unix/Unix-like systems. If we don't disable this user, it will make it easier for attackers to perform brute-force attacks against the root account.
Before disabling root access, we need to create a new user with the right to use the SSH service and add them to the sudoers list.
1. Access the SSH server using the "root" user first.
```bash
ssh root@202.150.169.245
```
2. Once logged in to the SSH server, create a new user and group. (You can refer to `man useradd` for more information)
```bash
groupadd ditatompel
useradd -s /bin/bash -d /home/ditatompel -g ditatompel -G root -m ditatompel
```
3. Set the password for this new user with the command `passwd ditatompel`.
![Create User](create-user.png#center)
4. Then, add the "ditatompel" user to the sudoers list. Edit the `/etc/sudoers` file and add the following permission:
```plain
ditatompel ALL=(ALL) ALL
```
5. Next, edit the `/etc/ssh/sshd_config` file and add/edit the following configuration:
```plain
PermitRootLogin no
AllowUsers ditatompel
```
6. Restart the SSH daemon:
```bash
service sshd restart #(For CentOS, etc.)
/etc/init.d/ssh restart #(for Debian)
/etc/rc.d/sshd restart #(FreeBSD, Arch, Gentoo, etc.)
```
> **Important:** After restarting, ensure that any currently connected SSH sessions do not get terminated or closed so you can still access and edit the configuration if there's an error.
7. Try accessing the SSH server using the new user, which is "ditatompel".
```bash
ssh ditatompel@202.150.169.245
```
## Changing the Default SSH Port (Optional)
Changing the default SSH port (`22`) can help prevent brute-force attacks that simply grab scripts from the internet since most brute-force SSH scripts default to port `22` for their attack attempts.
**NOTE:** If your server's firewall is active, you'll need to open access to the new port, for example if you're using `iptables`:
```bash
iptables -A INPUT -p tcp --dport 1337 -j ACCEPT
iptables save
service iptables restart
```
- Remember not to close any existing SSH connections that are already connected to avoid unwanted issues.
Next, to change the port, edit the `/etc/ssh/sshd_config` file and add/edit the following configuration:
```plain
Port 1337
```
Then, restart the SSH daemon.
As we can see, the SSH daemon is now listening on port `1337`. To confirm this, you can use the `netstat` command.
```bash
netstat -plnt
```
Finally, always test again to ensure that your server can be accessed.
## Using Public and Private Keys
1. First, create a _keypair_ for SSH client and SSH server using `ssh-keygen`.
```bash
ssh-keygen -b 4048 -f oldServer-169-245 -t rsa -C "ditatompel@oldServer-169-245"
```
This will generate two files: `oldServer-169-245` (private key) and `oldServer-169-245.pub` (public key). The former is our private key, while the latter is our public key that we'll place on our server.
2. Move these two files to the `~/.ssh` directory and change their permissions to `600`.
```bash
mv oldServer-169-245 oldServer-169-245.pub ~/.ssh/
find ~/.ssh/ -type f -exec chmod 600 {} +
```
![SSH-keygen](sshkeygen.jpg#center)
3. On the server, create a hidden directory `.ssh` in the user's home directory (`ditatompel`) and change its permissions to `700`.
```bash
mkdir ~/.ssh; chmod 700 ~/.ssh
```
4. Copy our public key to the remote PC (_SSH Server_) with the name `authorized_keys` and file permission `600`. (You can use `sftp` or `scp` to copy the file):
Example:
```bash
cd ~/.ssh
sftp -P 1337 ditatompel@202.150.169.245
```
```plain
sftp> put oldServer-169-245.pub /home/ditatompel/.ssh/authorized_keys
sftp> chmod 600 /home/ditatompel/.ssh/authorized_keys
```
![SFTP](sftp.png#center)
5. After that, edit the file `/etc/ssh/sshd_config` and add/configure the following to prevent users from accessing shells even if they know the password, and force them to use private keys:
```plain
PasswordAuthentication no
```
6. Restart SSH _daemon_ and try again with the command:
```bash
ssh -i ~/.ssh/oldServer-169-245 -p 1337 ditatompel@202.150.169.245
```
![SSH pass](ssh-pass.png#center)
## Managing Server Using FISH Protocol
This is my favorite part, and I think there might be some people who don't know about it yet.
**FISH** (_Files transferred over Shell protocol_) is a network protocol that uses **Secure Shell (SSH)** or **Remote Shell (RSH)** to transfer files between computers. We use **Dolphin**, which is already built-in with **KDE**. In addition to Dolphin, KDE users can also use `Konqueror` for the FISH protocol. For Gnome users, you can also use `Nautilus` with a third-party plugin.
To do this, simply click on the breadcrumb navigation directory and type `{protocol}{user}@{server}:{port}/{directory}` and press Enter.
Example :
```plain
fish://ditatompel@202.150.169.245:1337/var/www/path/to/directory/you/want/to/access/
```
![Fish protocol](fish.png#center)
After that, we will be prompted to enter our SSH password. However, there is a problem that FISH protocol on Dolphin/Konqueror does not know whether we are using public and private keys to access the server.
So, we can take advantage of the **ssh config** feature (located in `~/.ssh/config` for per-user configuration or `/etc/ssh/sshd_config` for system-wide).
For per-user configuration, there is usually no file `~/.ssh/config`, so we need to create it first by adding a configuration `IdentityFile` so that the program knows that we must use our **private key** SSH:
```plain
IdentityFile /home/dit/.ssh/oldServer-169-245
```
What if we have many servers and many private keys for each server? Let's continue reading.
## Configuring ~/.ssh/config
For system administrators responsible for managing numerous servers with diverse login access requirements, recalling port numbers, passwords, users, and so on can be a daunting task. Not to mention keeping track of application access on each server. Therefore, we can utilize the SSH config feature that enables us to access the shell by simply remembering the IP address and passphrase of each server.
Here is an example configuration for multi-server identities:
```plain
Host 202.150.169.245
Hostname 202.150.169.245
User ditatompel
Port 1337
IdentityFile /home/dit/.ssh/oldServer-169-245
Host xxx.xx.xx.xxx
HostName xxx.xx.xx.xxx
User ditakeren
Port 12345
IdentityFile /home/dit/.ssh/blahblah1
Host xxx.xxx.xxx.xx
Hostname xxx.xxx.xxx.xx
User ditacakep
Port 23213
IdentityFile /home/dit/.ssh/blahblah2
# dan seterusnya
```
![~/.ssh/config](ssh-config.png#center)
With this, we can use the SSH command with:
```bash
ssh 202.150.169.245
```
or by adding it to a network directory by accessing **Network** > **Add Network directory**, and filling in the necessary remote PC (SSH server) information.
![Fish Protocol](fish-protocol1.png#center)
That's all from me for now; please feel free to add or correct as you see fit, I would greatly appreciate it.
References:
- [http://linux.die.net/man/5/ssh_config](http://linux.die.net/man/5/ssh_config).
- [http://kb.mediatemple.net/questions/1625/Using+an+SSH+Config+File](http://kb.mediatemple.net/questions/1625/Using+an+SSH+Config+File).