Keep learning forward
To be updated ...#TIL : How SMTP works
When a email send through an SMTP (with authentication), every SMTP server is a hop in mail routing. So it will transfer to localmail or forward the email to next hop (shortest distance via DNS MX record).
And standard port of SMTP is 25 (unsecured, but can upgrade to TLS via STARTTLS command).
$ nslookup -type=mx gmail.com 8.8.8.8 Server: 8.8.8.8 Address: 8.8.8.8#53 Non-authoritative answer: gmail.com mail exchanger = 20 alt2.gmail-smtp-in.l.google.com. gmail.com mail exchanger = 5 gmail-smtp-in.l.google.com. gmail.com mail exchanger = 30 alt3.gmail-smtp-in.l.google.com. gmail.com mail exchanger = 10 alt1.gmail-smtp-in.l.google.com. gmail.com mail exchanger = 40 alt4.gmail-smtp-in.l.google.com. Authoritative answers can be found from:
So shortest SMTP of gmail.com domain is
gmail-smtp-in.l.google.com
$ telnet gmail-smtp-in.l.google.com 25
#TIL : Send ENTER key to kernel
When you try to send an Enter keyboard to linux kernel, it looks like nothing happens.
This is because you only send a key press (KEY DOWN) but don't send an key release (KEY UP) event after that.
#TIL : BASH tracing commands
Thank Hiro Ishii for teaching me this
set -x
will print all running commands in your bash scriptSo I dove in and look for all set options of BASH.
And this is what I got , http://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
#TIL : BASH return a value in function
Creating function is a good way to refactor your bash script. But BASH doesn't support returning a value in true way, so it makes a bit of challenge to handle that.
You can use this trick
hello() { echo "Hello $1" } hw=$(hello "KhanhIceTea") echo $hw
But what if you want to echo log message in hello function, it will be merged to returned value.
hello() { echo "System is weaking up and brush its teeth :))" echo "Hello $1" } hw=$(hello "KhanhIceTea") echo "This is returned value of hello function :" echo $hw
This is a how to resolve it, forwarding log message to stderr instead of stdout by default
hello() { echo "System is weaking up and brush its teeth :))" >&2 echo "Hello $1" } hw=$(hello "KhanhIceTea") echo "This is returned value of hello function :" echo $hw
Where there is a shell, there is a way !
#TIL : BASH exiting on first error
Setting a flag
set -e
to bash script will let the script exit on first error occurs, so if you want to ignore a command just adding|| true
to suffixset -e errorCmd $1 || true echo "Run here !"
And opposite of
set -e
isset +e
, haha of course !set +e errorCmd $1 echo "Still run here !"
#TIL : Zip compressing list of files
To specify a list of compressed files when using zip cli tool, you could use
-@ [file_list]
flag. Andfile_list
is a file contains list of compressed file (new line separated)Example
$ zip changed.zip -@ changed_files.txt
Or use stdin pipe
$ find . -mmin -60 -print | zip changed_1_hour_ago -@
This will zip all changed files 1 hour ago
#TIL : Blocking specified country to prevent from DDOS
Last day I checked system logs and got a lot of warning messages mentioned that my server has been attack via Brute-force. So I decided to blocked some countries from connecting to attacked ports (21, 25). They are China, Russia and US.
This site provides a list of IP blocks of specified country
#TIL : TCP FIN timeout
The TCP FIN timeout belays the amount of time a port must be inactive before it can reused for another connection. The default is often 60 seconds, but can normally be safely reduced to 30 or even 15 seconds:
net.ipv4.tcp_fin_timeout = 15
Ref : https://www.linode.com/docs/web-servers/nginx/configure-nginx-for-optimized-performance
#TIL : Lock and unlock a user password
In Linux, you can prevent a user from login by locking it.
Lock
$ sudo passwd -l [user]
Unlock
$ sudo passwd -u [user]
#TIL : Generate dhparam file faster
openssl uses strong prime (which is useless for security but requires an awful lot more computational effort. A "strong prime" is a prime p such that (p-1)/2 is also prime). So it will be faster if we add option
-dsaparam
to the command$ openssl dhparam -dsaparam -out /etc/ssl/private/dhparam.pem 4096
#TIL : Grep : find a string in folder
Grep is a greate tool for searching a string in files.
Syntax
$ grep -nr '[string]' [folder]
If you want to show surrounding lines the result, add flag
-C [number]
to the command$ grep -nr -C 3 'hello' src
#TIL : Ansible playbook : skip to task
You can skip to a task by its name by adding parameter
--start-at
$ ansible-playbook playbook.yml --start-at="[your task name]"
#TIL : Mycli : a new good cli MySql Client
This tool is written in Python with super cool features (auto-complete and colors).
Worth a shot !
Install
$ pip install mycli
Usage
$ mycli -h 127.0.0.1 -P 3306 -u root
Screencast
#TIL : Enable reverse proxy in CentOS
CentOS with SELinux enabled by default will block any http proxy connection. So you have to enable this permission.
Temporary enable
$ /usr/sbin/setsebool httpd_can_network_connect 1
Permanent enable
$ /usr/sbin/setsebool -P httpd_can_network_connect 1
#TIL : Create SSH tunnel manually
SSH Tunnel is a fast way to transfer traffic through unsafe internet today. It would be used in MySQL connect, FTP connect or HTTP connect, ...
Syntax :
$ ssh -L [local_port]:[remote_endpoint]:[remote_port] [ssh_user]:[ssh_ip]
Example :
Lets say you have a EC2 instance (123.45.67.89) and remote DB instance (98.76.54.32) listening port 3306
$ ssh -L 3307:98.76.54.32:3306 root@123.45.67.89
Testing ssh tunnel
$ telnet 127.0.0.1 3307 $ # or $ mysql -h 127.0.0.1 -P 3307 -u root -p
#TIL : Scope and Closure
Run this code
for (var i=1; i<=5; i++) { setTimeout( function timer(){ console.log( i ); }, i*1000 ); }
What you expected
1 2 3 4 5
But, result is
6 6 6 6 6
Solution is
for (var i = 1; i <= 5; i++) { setTimeout((function timer(j) { return function() { console.log(j); } })(i), i * 1000); }
or
for (var i=1; i<=5; i++) { (function(j){ setTimeout( function timer(){ console.log( j ); }, j*1000 ); })(i); }
#TIL : Eval function and with block
JS code will be slower if engine detects any of 'eval' function or 'with' block b/c compiler stop optimizing the code
#TIL : Remap Capslock to Control key
Edit file
/etc/default/keyboard
and setXKBOPTIONS="ctrl:nocaps"
Then, logout and log in again to impact
#TIL : Ping Google to crawl updated content
When you post new content to your website, the fastest way is ping search engines to notify them. After that, they will try to crawl and index your page.
One way to ping search engines is using XMLRPC ping
This is a example XMLRPC request (HTTP POST request with xml body)
Request
> POST /ping/RPC2 HTTP/1.1 > Host: blogsearch.google.com > User-Agent: curl/7.47.0 > Accept: */* > content-type: application/xml > Content-Length: 239 > <?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>weblogUpdates.extendedPing</methodName> <params> <param> <value>Page Title</value> </param> <param> <value>http://example.com/helloworld.html</value> </param> </params> </methodCall>
Response
< HTTP/1.1 200 OK < Content-Type: text/xml; charset=ISO-8859-1 < X-Content-Type-Options: nosniff < Date: Tue, 08 Aug 2017 05:04:01 GMT < Server: psfe < Cache-Control: private < X-XSS-Protection: 1; mode=block < X-Frame-Options: SAMEORIGIN < Accept-Ranges: none < Vary: Accept-Encoding < Transfer-Encoding: chunked < <?xml version="1.0"?> <methodResponse><params> <param><value><struct> <member> <name>flerror</name><value><boolean>0</boolean></value> </member> <member> <name>message</name><value>Thanks for the ping.</value> </member> </struct></value></param> </params></methodResponse>
Popular XML Servers
http://blogsearch.google.com/ping/RPC2 http://api.moreover.com/ping http://bblog.com/ping.php http://bitacoras.net/ping http://blog.goo.ne.jp/XMLRPC http://blogmatcher.com/u.php http://coreblog.org/ping/ http://mod-pubsub.org/kn_apps/blogchatt http://www.lasermemory.com/lsrpc/ http://ping.amagle.com/ http://ping.cocolog-nifty.com/xmlrpc http://ping.exblog.jp/xmlrpc http://ping.feedburner.com http://ping.myblog.jp http://ping.rootblog.com/rpc.php http://ping.syndic8.com/xmlrpc.php http://ping.weblogalot.com/rpc.php http://pingoat.com/goat/RPC2 http://rcs.datashed.net/RPC2/ http://rpc.blogrolling.com/pinger/ http://rpc.pingomatic.com http://rpc.technorati.com/rpc/ping http://rpc.weblogs.com/RPC2 http://www.blogpeople.net/servlet/weblogUpdates http://www.blogroots.com/tb_populi.blog?id=1 http://www.blogshares.com/rpc.php http://www.blogsnow.com/ping http://www.blogstreet.com/xrbin/xmlrpc.cgi http://xping.pubsub.com/ping/
#TIL : Runing old java applets on brower
Mostly morden browser has stop support Java plugins, so you can't run Java applet on browser.
Temporary way :
- run in IE or Safari
- run in an old Firefox (version 23)
And what if old java applet can't be runned on Java 8 because of weak signature algorithm. Try this
- Open
java.security
file :- In MacOS, located in
/Library/Java/JavaVirtualMachines/jdk[jdk-version].jdk/Contents/Home/jre/lib/security
- In Windows, located in
C:\Program File x86\Java\jre\lib\security
- In MacOS, located in
- Comment this line,
jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
- Rerun applet
#TIL : realpath function
If you pass a non-exists path to function
realpath
, it returns empty string. So please don't do something like :function storage_path($folder) { return realpath(__DIR__.'/storage/'.$folder); }
if you expect it return full path of new folder !
#TIL : Cleaning up old linux kernels
Last day, I try to reboot a production server which has out-of-space /boot (I upgraded many kernels without rebooting, so system doesn't clean up old ones). And in the end, doom day had come ! It installed new kernel failed and booting to that kernel. My system crashed !
So, I learned from it :
- Never ever upgrade kernel without cleaning up old ones (just reboot)
- Never ever reboot a production without backup
- MORE IMPORTANT, NEVER do 2 above things at same time in the weekend !!!
Solution :
Check current kernel :
uname -r
List all kernels :
dpkg --list | grep linux-image
Remove a kernel :
sudo apt-get purge linux-image-x.x.x-x-generic
Finally, update grub after removing all old kernels :
sudo update-grub2
YOLO command for DEBIAN distros (to remove all of old kernels in 1 line), from AskUbuntu
dpkg --list | grep linux-image | awk '{ print $2 }' | sort -V | sed -n '/'`uname -r`'/q;p' | xargs sudo apt-get -y purge
THEN,
sudo reboot
#TIL : HTTP2 supported for python requests library
The sophisticated http client in Python is
requests
, it has simple API but powerful features. You can use it for crawling, sending request to third-party API or writing tests.Btw, at this moment it doesn't support HTTP/2 protocol (actually we often doesn't need its
Server Push
orMulti resource stream
features). But sometime the API endpoint only supports HTTP/2 like Akamai Load Balacing service.The hero is new library named
hyper
, it has been developing to support full HTTP/2 specs. But if all we need is requesting single request to a HTTP/2 server. It works like a charm.Installation
$ pip install requests $ pip install hyper
Usage
import requests from hyper.contrib import HTTP20Adapter s = requests.Session() s.mount('https://', HTTP20Adapter()) r = s.get('https://cloudflare.com/') print(r.status_code) print(r.url)
This mean any url has prefix
https://
will be hanlded by HTTP20Adaper of hyper libraryNotice
If you run above example, you will see the result
200 https://cloudflare.com/
While you expected it would auto-follow redirect to the page
https://www.cloudflare.com/
We can fix it by using the newer version than
0.7.0
to fix the header key bytestring issue$ pip uninstall hyper $ pip install https://github.com/Lukasa/hyper/archive/development.zip
Then try it out !!!
#TIL : Free sandbox server for development
We can use Heroku as a forever-free sandbox solution for testing or hosting micro service. Adding a credit card to have 1000 free computing hours.
Heroku will make a service down if no received request come. We can use a cronjob-like service to check service health and keep it live !!! ;)
Cronjob check health SASS : pingdom, statuscake, port-monitor, uptimerobot
Btw, I don't recommend you keep service live but no use, it makes Heroku infrastructure heavy and THAT'S NOT FAIR for them !
#TIL : Gearman bash worker and client
Gearman is a awesome job queue service that helps you scale your system. In smaller context, it can help us to run a background woker for minor tasks like backup data, cleaning system.
Install :
$ sudo apt install gearman-job-server gearman-tools
Create a worker bash script
#!/bin/bash echo $1 echo $2
Run worker,
-w
means run as worker mode ,-f test
means function name will betest
$ chmod +x worker.sh $ gearman -w -f test xargs ./worker.sh
Sending job
$ gearman -f test "hello" "hogehoge"
Sending background job
$ gearman -b -f test "hello" "hogehoge"
#TIL : Resolving conflict like a boss
When using git merge new branch to old branch, you just want use all
ours
ortheirs
version but be lazy to update every conflicted file.grep -lr '<<<<<<<' . | xargs git checkout --ours
Or
grep -lr '<<<<<<<' . | xargs git checkout --theirs
Explain : these commands will find any file contains
<<<<<<<
string (conflicted file) and rungit checkout --[side]
#TIL : Reducing docker image the right way
When building an image, Docker engine commit file system layer on every command (RUN, ADD, COPY). So next time you installing packages from package manager likes apt, yum, pacman, ...remember clean their cache in same line.
BAD WAY
RUN apt-get update RUN apt-get install git # Something here # End of file RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RIGHT WAY
RUN apt-get update && apt-get install -y git zip unzip && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#TIL : Changing channel from alpha to stable will remove ALL DATA
On MacOS, changing Docker channel will remove all data (includes volumes, images, networks and ... everything).
Because Docker on Mac using a minimal Linux machine to host docker engine, so changing machine means discarding all old data. So BECAREFUL !
#TIL : zcat : decompressing pipe tool
zcat
is a tool that creates a pipe from gz file. It makes command cleaner and faster (maybe). You don't have to decompress gz file before using next tool.Examples :
Finding string in gzip text file
$ zcat secret.gz | grep '42'
Importing SQL backup file
$ mysqldump -u root -p db_name1 | gzip > db_name.sql.gz $ zcat db_name.sql.gz | mysql -u root -p db_name_2
#TIL : Using BSD find util to find and exec command on file and folder
Simple syntax of find
$ find [find_path] -type [file_type] -exec [command] {} \;
Add filename matching pattern to filter the result
$ find [find_path] -name "*.php" -type [file_type] -exec [command] {} \;
Where
file_type
is :- b : block special
- c : character special
- d : directory
- f : regular file
- l : symbolic link
- p : FIFO
- s : socket
Examples:
Fix common file and directory permissions
$ find . -type f -exec chmod 644 {} \; $ find . -type d -exec chmod 755 {} \;
Check syntax all PHP files
$ find . -type f -name "*.php" -exec php -l {} \; | grep -v 'No syntax errors detected'
Removed all log files
$ find . -type f -name "*.log" -exec rm -f {} \;
WANT MORE ???
$ man find