//Enable the module by typing:
sudo a2enmod ssl
// Configure SSL
sudo vim /etc/apache2/sites-available/default-ssl.conf
ServerAdmin your gmail
ServerName weishihhsun.com
ServerAlias www.weishihhsun.com
SSLCertificateFile /weishihhsun/ssl_key/your certificate.crt
SSLCertificateKeyFile /weishihhsun/ssl_key/your certificate key.key
SSLCertificateChainFile /weishihhsun/ssl_key/your certificate chain.ca-bundle
//After you have enabled SSL, you'll have to restart the web server for the change to be recognized:
sudo service apache2 restart
Senior Software Developer with 18+ years of programming experience - 7 years in C/C++, delivering on-time, on-budget multimedia services; 5 years of experience in Java, PHP, JS, HTML5, and 6+ years in Golang, Python and Objective-C. Website: https://blog.gametechtutorial.com
Personal Project
Tuesday, October 4, 2016
Monday, September 12, 2016
How to Automatically Scale Up Your Application on AWS ?
This basic rule is you have to make your application servers and databases to be independent of each other. The application servers are only responsible for processing game or business logic without saving any cache data at local. The databases are used for saving game or user data. In front of the application servers, it is necessary to set up a load balancer - while there is any problem occurring to make a server become unavailable - to redirect the user traffic to available servers.
Moreover, if you want to reduce the overhead of MYSQL such as the number of current connections to improve performance, you can use shared memory servers like Redis or Memcached to save user sessions to decrease the number of SQL queries on MYSQL.
In addition, NoSQL database, Couchbase or MongoDB, would be a better alternative to replace MYSQL database. It can dramatically improve the performance of web applications.
As the user traffic grows, you can easily add one EC2 application server on AWS or improve MYSQL/NoSQL database specs to meet this need.
The proposed methods below will teach you how to set up an auto-scale
infrastructure for your applications.
Initial an EC2 instance and deploy your Java Application on this EC2 and set up a startApp script below at startup time.
vim startapp
#!/bin/bash
cd /home/weishihhsun/app/
nohup java -jar p2pServer.jar &
sudo cp startapp /etc/init.d
sudo chmod +x /etc/init.d/startapp
sudo update-rc.d startapp defaults 98 02
98 and 02 are the start and stop sequence numbers respectively.
Both are numbers between 00 and 99 and specify how early or late a service is started or killed
By doing so, your Java or Tomcat application would be booted up at startup time.
The usage of CPU, for example, is more than 80%, then automatically increase the EC2 instance of a server; if it is below 10%, then decrease the EC2 instance of a server.
To conclude, you have learned how to build a high availability and scalability infrastructure for your applications. By making use of the proposed methods, you can automatically scale up your application servers developed by PHP, Java, C# or C/C++ on AWS, as long as you make your applications independent of the database.
Moreover, if you want to reduce the overhead of MYSQL such as the number of current connections to improve performance, you can use shared memory servers like Redis or Memcached to save user sessions to decrease the number of SQL queries on MYSQL.
In addition, NoSQL database, Couchbase or MongoDB, would be a better alternative to replace MYSQL database. It can dramatically improve the performance of web applications.
As the user traffic grows, you can easily add one EC2 application server on AWS or improve MYSQL/NoSQL database specs to meet this need.
The proposed methods below will teach you how to set up an auto-scale
infrastructure for your applications.
1.Create StartApp Script for Java Application/Tomcat at startup time
Initial an EC2 instance and deploy your Java Application on this EC2 and set up a startApp script below at startup time.
vim startapp
#!/bin/bash
cd /home/weishihhsun/app/
nohup java -jar p2pServer.jar &
sudo cp startapp /etc/init.d
sudo chmod +x /etc/init.d/startapp
sudo update-rc.d startapp defaults 98 02
98 and 02 are the start and stop sequence numbers respectively.
Both are numbers between 00 and 99 and specify how early or late a service is started or killed
By doing so, your Java or Tomcat application would be booted up at startup time.
2. Create an image of EC2 instance on AWS
You need to create an image of EC instance - a clone of this server - by AWS Control UI.3. Setup Auto-Scaling Group
You need to add an image of EC2 instance to the auto-scaling group and set up some thresholds to trigger different types of alarms, such as the usage of CPU, hard disk, and internet traffic.The usage of CPU, for example, is more than 80%, then automatically increase the EC2 instance of a server; if it is below 10%, then decrease the EC2 instance of a server.
To conclude, you have learned how to build a high availability and scalability infrastructure for your applications. By making use of the proposed methods, you can automatically scale up your application servers developed by PHP, Java, C# or C/C++ on AWS, as long as you make your applications independent of the database.
Monday, September 5, 2016
How to secure REST API ?
I recommend you implement the protocol of OAuth 2.0 to secure your REST API because the spec of OAuth 2.0 shows that the authorization server must require the use of TLS when sending requests using password authorization as shown below.
HTTP Basic Authorization Request Message:
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw
Client_id : Client Account
Client_secret : Client Password
If you don`t implement TLS/SSL, your plaintext of account and password might be intercepted by Man In Middle Attack.
On the other hand, OAuth 1.0 shows that TLS is must feature to secure your plaintext but did not mention in detail what version of TLS should be adapted or who should implement it
Therefore I propose three methods outlined below to pretend your REST API.
1. Must Use SSL/TLS
You must implement the TLS/SSL before sending the plaintext of password and account to Authorization Server. By doing so, your plaintext would be less vulnerable to being intercepted.
In addition, for telecom application services, they also implement TLS to secure SIP - they set up a secure channel by TLS between the client and the server first and do HTTP Basic Digest Authentication, then start to make, answer or transfer the call in SIP over this secure channel. This is why TLS/SSL is widely used to secure communication layers in the different industry, such as game, telecom, and e-commerce.
2. Shorten the lifetime of a token key
After finishing the authorization, the client will get the access token with the lifetime. You can shorten the lifetime to reduce the risk of a token being hijacked.
3. Implement Your asymmetric encryption algorithm to encrypt plain text values of account and password
What if one day the TLS/SSL becomes not secure, the same situation will happen again that you must implement your mechanism to encrypt your plaintext of account and password.
Take RSA for example, you can implement the method as shown below.
Public and private key are generated by your server. You can give the public key to the client in private.
1. Client :
tokenUserId = encryption (useId::random key, publicKey)
tokenPassword = encryption (Password::random key, publicKey)
The client encrypts the values of userId and Password by public Key and random key and sends tokenUserId and tokenPassword to the server.
The random key could be generated by time stamp or any mechanism you prefer.
2.Server :
UserId = decryption (tokenUserId, privateKey)
Password = decryption (tokenPassword, privateKey)
The server decrypts those encrypted tokens - tokenUserId and tokenPassword - with the private key and starts to do HTTP Basic Authorization.
Of course, you can use any asymmetric encryption algorithm you like.
Reference :
RFC 5849 The OAuth 1.0 Protocol
RFC 6749 The OAuth 2.0 Authorization Framework
RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
RFC 5630 The Use of the SIPS URI Scheme in the Session Initiation Protocol (SIP)
HTTP Basic Authorization Request Message:
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw
Client_id : Client Account
Client_secret : Client Password
If you don`t implement TLS/SSL, your plaintext of account and password might be intercepted by Man In Middle Attack.
On the other hand, OAuth 1.0 shows that TLS is must feature to secure your plaintext but did not mention in detail what version of TLS should be adapted or who should implement it
Therefore I propose three methods outlined below to pretend your REST API.
1. Must Use SSL/TLS
You must implement the TLS/SSL before sending the plaintext of password and account to Authorization Server. By doing so, your plaintext would be less vulnerable to being intercepted.
In addition, for telecom application services, they also implement TLS to secure SIP - they set up a secure channel by TLS between the client and the server first and do HTTP Basic Digest Authentication, then start to make, answer or transfer the call in SIP over this secure channel. This is why TLS/SSL is widely used to secure communication layers in the different industry, such as game, telecom, and e-commerce.
2. Shorten the lifetime of a token key
After finishing the authorization, the client will get the access token with the lifetime. You can shorten the lifetime to reduce the risk of a token being hijacked.
3. Implement Your asymmetric encryption algorithm to encrypt plain text values of account and password
What if one day the TLS/SSL becomes not secure, the same situation will happen again that you must implement your mechanism to encrypt your plaintext of account and password.
Take RSA for example, you can implement the method as shown below.
Public and private key are generated by your server. You can give the public key to the client in private.
1. Client :
tokenUserId = encryption (useId::random key, publicKey)
tokenPassword = encryption (Password::random key, publicKey)
The client encrypts the values of userId and Password by public Key and random key and sends tokenUserId and tokenPassword to the server.
The random key could be generated by time stamp or any mechanism you prefer.
2.Server :
UserId = decryption (tokenUserId, privateKey)
Password = decryption (tokenPassword, privateKey)
The server decrypts those encrypted tokens - tokenUserId and tokenPassword - with the private key and starts to do HTTP Basic Authorization.
Of course, you can use any asymmetric encryption algorithm you like.
To conclude, the safest method to secure your important data sent over the internet is using proprietary protocol - Skype, What`s app, Line, for example, all have implemented their proprietary encryption and decryption algorithms to make the data more secure instead of following the standard. Perpahs cracking a proprietary protocol is harder than the standard one.
Reference :
RFC 5849 The OAuth 1.0 Protocol
RFC 6749 The OAuth 2.0 Authorization Framework
RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
RFC 5630 The Use of the SIPS URI Scheme in the Session Initiation Protocol (SIP)
Thursday, August 18, 2016
How to secure your Linux ?
Get Started
There are four common and useful methods for you to secure and check your Linux.- Port Scan
- Firewall
- Update Security package
- Antivirus
Port Scan
You can check your system by scanning your port number. Once you find out some ports that are open and not used, remember to close them and stop their related services accordingly.-
Install port scan tool
sudo install nmap
-
Execute Port Scan command to scan Port from 1 to 65535
nmap -p 1-65535 -T4 -A -v [Target IP]
Firewall
The fundamental rule to improve the security of your Linux is your system merely opens necessary and required ports for your services. I strongly recommend you to set up restrictions on port 22 to avoid being attacked by SSH Brute Force. Hopefully, DenyHost is a smart firewall that can automatically parse SSH Log and detect malicious IPs to setup block rules for you.Update Security package
Update your system with latest security packages automatically.Install this package if it isn't already installed using
sudo apt-get install unattended-upgrades
To enable it type
sudo dpkg-reconfigure unattended-upgrades
and select "yes".
AntiVirus
Scan and check your system regularly with the following antivirus software.-
Install Virus
sudo apt-get install clamav
-
Update Virus code
sudo freshclam
-
Scan system
sudo clamscan --remove=yes -i -r ./
Monday, August 15, 2016
Apache Problem due to (24)Too many open files - Solution
After running web services on Apache for few years, my web suddenly could not be accessed because of given an error "HTTP WARNING: HTTP/1.1 403 Forbidden".
When checking the Apache Error log, I found an error message as shown below.
The solution to this problem is to increase the maximum number of open files and user processes by the following settings.
vim /etc/security/limits.conf
root soft nofile 32768
root hard nofile 32768
root soft nproc 4096
root hard nproc 4096
When checking the Apache Error log, I found an error message as shown below.
(24)Too many open files: /var/www/html/.htaccess pcfg_openfile: unable to check htaccess file, ensure it is readable
The solution to this problem is to increase the maximum number of open files and user processes by the following settings.
vim /etc/security/limits.conf
root soft nofile 32768
root hard nofile 32768
root soft nproc 4096
root hard nproc 4096
Wednesday, August 3, 2016
How to Build an Android Project using Cocos2d-x 3.6 with Eclipse ?
1.Install
Download and install the following libs and SDKs.
JDK
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Android SDK
http://developer.android.com/sdk/installing/index.html?pkg=tools
Android NDK 10e
http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip
Apache Ant
http://ant.apache.org/bindownload.cgi
2. Configure settings using Eclipse
Goto Eclipse --> Preference --> C/C++ --> Build --> Environment
Edit the following settings as shown below.
ANDROID_SDK_ROOT
/Users/User/Applications/Android/sdk
ANR_ROOT
/Users/User/Desktop/cocos2d-x/apache-ant-1.9.7/bin
COCOS_CONSOLE_ROOT
/Users/User/Desktop/cocos2d-x/cocos2d-x-3.6/tools/cocos2d-console/bin
NDK_ROOT
/Users/User/Desktop/cocos2d-x/android-ndk-r10e
PATH
/usr/bin:/bin:/usr/sbin:/sbin:/Users/User/Desktop/cocos2d-x/cocos2d-x-3.6/tools/cocos2d-console/bin
Edit NDK location
3. Import Cocos2d-x Lib
3.1 In Package Explorer, click import button --> Android --> Existing Android Code Into Workspace
3.2 Select Cocos2d-x-3.6 --> cocos --> platform --> android --> java
4. Import Source Codes
4.1 Click import button --> Android --> Existing Android Code Into Workspace --> select your android source codes project
4.2 Check your project have a link to Cocos2d-x lib
Select your project --> Properties --> Android --> Library
5. Run Configuration
5.1. Goto Run --> Configurations --> Android Application --> Tab Android
Name : Your Name
Project : Click Browse button and select the path of your Source Code
5.2. Goto Run --> Configurations --> Android Application --> Tab Target
Run on Android devices
Check option - Launch on all compatible devices/AVDs
Run on Simulator
Check option - Automatically pick compatible device : Always uses preferred AVD if set below, launches on compatible device/ AVD otherwise.
5.3. Execute Run button
Monday, July 25, 2016
How to setup a TURN Server for your WebRTC application ?
Get Started
Developing a WebRTC application is easy, but solving the issue of NAT could be a difficult task. If you want to build your WebRTC environment without using any 3rd Party cloud solutions, I think you should take a look at an open source lib - rfc5766-turn-server. Because it not only supports TURN, but also STUN.
In this tutorial, you will learn how to set up a STUN & TURN server.
1.Download rfc5766-turn-server package
$ wget http://ftp.cn.debian.org/debian/pool/main/r/rfc5766-turn-server/rfc5766-turn-server_3.2.4.4-1_amd64.deb
2. Install
$ sudo apt-get update
$ sudo apt-get install gdebi-core
$ sudo gdebi rfc5766-turn-server_3.2.4.4-1_amd64.deb
Refer to docs in folder /usr/share/doc/rfc5766-turn-server
vim /opt/etc/turnserver.conf.default
3. Configuration
$ sudo vi /etc/turnserver.conf
// Setup IP address - listening-ip and external-ip are required to set up on EC2 of AWS.
listening-ip=172.31.4.37
external-ip=54.223.149.60
// If TURN server is used for WebRTC,please set long-term credential mechanism as shown below.
lt-cred-mech
// Add a user
user=weishihhsun:mypassword
// Setup realm
realm=mycompany.org
4. Start TURN Server
sudo turnserver -c /usr/local/etc/turnserver.conf --daemo
5. Setup TURN Server`s IP address
"iceServers": [{
"url": "stun:stun.l.google.com:19302"
}, {
"url": "turn:54.223.149.60", // Your Server
"username": "weishihhsun", // your Account
"credential": "mypassword" // Your Password
}]
6. Open firewall`s ports
TCP 443
TCP 3478-3479
TCP 32355-65535
UDP 3478-3479
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 3478:3479 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 32355:65535 -j ACCEPT
iptables -A INPUT -p udp -m tcp --dport 3478:3479 -j ACCEPT
Friday, July 15, 2016
How to solve a network problem ?
Have you ever had a network problem due to packet lost or some unknown issues in your routers ? How could you find out those issues may be caused by your routers or Internet Service Provider ?
The following instructions will guide you how to figure it out.
// 1. Download mtr
// 2. Execute the following command to check whether or not there is a packet lost problem in your network node.
sudo mtr -c 100 -r [target IP]
// 3. Then execute traceroute
traceroute [target IP]
You will know that the network node is shown in IP address or Domain Name.
If it is IP address, it probably could be the router; if it is the domain name, it might be your ISP`s network devices.
// 4 Download nmap
https://nmap.org/download.html
// 5. Dump router`s info and you can find out what your router is, so as to fix it.
nmap -A -T4 router IP
Ex:
EricWeis-MacBook-Air:~ EricWei$ nmap -A -T4 192.168.11.1
Starting Nmap 7.12 ( https://nmap.org ) at 2016-07-07 23:33 JST
Stats: 0:01:47 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 80.00% done; ETC: 23:35 (0:00:27 remaining)
Nmap scan report for buffalo.setup (192.168.11.1)
Host is up (0.027s latency).
Not shown: 995 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain (status request not implemented)
80/tcp open http Buffalo AirStation http config
| http-auth:
| HTTP/1.0 401 Unauthorized
|_ Basic realm=AirStation
|_http-title: UNAUTHORIZED
2601/tcp open zebra Quagga routing software
2602/tcp open zebra Quagga routing software
49152/tcp open upnp Intel UPnP reference SDK 1.2 (Linux 2.4.20; UPnP 1.0)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.12%I=7%D=7/7%Time=577E6838%P=x86_64-apple-darwin13.4.0%r
SF:(DNSVersionBindReq,20,"\0\x1e\x02G\x81\x85\0\x01\0\0\0\0\0\0\x07version
SF:\x04bind\0\0\x10\0\x03")%r(DNSStatusRequest,E,"\0\x0c\x02H\x90\x84\0\0\
SF:0\0\0\0\0\0");
Service Info: OS: Linux; Device: WAP; CPE: cpe:/o:linux:linux_kernel:2.4.20
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 141.69 seconds
Thursday, June 16, 2016
Tutorial (2) : How to send Push Notifications to iPhone using Java ?
Generate aps_developer.p12 for JavaPNS
Download and Upzip openssl-0.9.8k_WIN32.zip
Goto windows dos command mode
// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_developer.cer -inform DER -out
aps_developer.pem -outform PEM
// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in
PushChatCert.p12
// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_developer.pem -inkey Push_Noenc.pem -certfile PushChat.certSigningRequest
-name "aps_developer" -out aps_developer.p12
Obtain Device token from iOS
Add the following code in the method of AppDelegate.didFinishLaunchingWithOptions
IOS Code:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert
| UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];
To setup registerForRemoteNotificationTypes for app to
receive notification message.
To extract device token by the following codes:
IOS Code:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
NSLog(@"My token is:%@", token);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSString *error_str = [NSString stringWithFormat: @"%@", error];
NSLog(@"Failed to get token, error:%@", error_str);
}
NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
NSLog(@"My token is:%@", token);
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSString *error_str = [NSString stringWithFormat: @"%@", error];
NSLog(@"Failed to get token, error:%@", error_str);
}
iOS device needs to implement two features: one is to
register app as receiving notification type, the other is to send its token to
backend JavaPNS via HTTP or TCP protocol.
Setup JavaPNS Sample code
Please add the following .jar library in your project:
1. bcprov-jdk15-146.jar
2. log4j-1.2.15.jar
3. JavaPNS_2.2.jar (
unzip JavaPNS_2.2_complete.zip )
4. Compile the source code : PushTest.java
(PS: Or simply import the testSample code by eclipse
and run it)
JavaPNS needs certificate aps_developer.p12,
and iOS token id to accomplish the function of sending Push Messages.
The following codes below detail how to make it work.
public static void main(String[] args) {
// iOS Private key as a p12 file exported by MAC
String keynotePath = "aps_developer.p12";
// iOS developer certificate password exported by MAC
String password = "Your Pasword";
// iOS device Token id
String token =
"Your Device Token";
// Test environment: Production or Sandbox(simulation)
String environment = "simulation";
// Push message mode: Simple or complex or thread
//
Simple: Simple msg, complex: complex message, thread: Add multiple threads
support
String pushMode = "complex";
// Number of received devices
String deviceNum = "1";
// Number of sender threads
String threadNum = "1";
/* Initialize Log4j to print logs to console */
configureBasicLogging();
/* Push an alert */
try {
pushTest(keynotePath, password, token,
environment, pushMode, deviceNum, threadNum);
} catch (CommunicationException e) {
e.printStackTrace();
} catch (KeystoreException e) {
e.printStackTrace();
}
}
How to generate iOS development certificate for Push Server ?
// For Development Environment// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_development.cer -inform DER -out aps_developer.pem -outform PEM
// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12 // Input your password
// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_developer.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_developer" -out aps_developer.p12
How to generate iOS Production certificate for Push Server?
// For Production// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_production.cer -inform DER -out aps_production.pem -outform PEM
// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12
// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_production.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_production" -out aps_production.p12
Next - Tutorial(1) : How to send Push Notifications to Android using Java ?
Subscribe to:
Posts (Atom)