* TLS Server는 다음과 같이 생성한다.
var tls=require('tls'); var fs=require('fs'); var serverOptions={ key:fs.readFileSync('./alnova2_key.pem'), cert:fs.readFileSync('./alnova2_cert.pem') }; var server=tls.createServer(serverOptions); //1) var port=4001; server.listen(port); function secureConnectionListener(clientStream){ clientStream.on('data',function(data){ console.log('got some data from the client',data); }); clientStream.write('Hello'); } server.on('secureConnection',connectionListener); //2) |
1) createServer의 serverOptions는 key, cert 이외에 requestCert(true일경우 접속하는 client에 certificate를 요구함, 기본적으로 false임) 및 rejectUnauthorized(Certificate Authorities에 인증되지 않은 접속은 거부함, 기본적으로 false임)
2) client가 접속하면 secureConnection event가 발생한다. 이때 tls.CleartextStream 객체가 전달되는데 data event를 listen하여 데이터를 읽거나 write 메소드(또는 end 메소드)로 write(write하고 종료)가능하다.
- tls.CleartextStream은 end 메소드로 접속 종료 가능하다.
* TLS Client 는 다음과 같이 생성한다.
var fs=require('fs'); var options={ key:fs.readFileSync('/path/private_key.pem), cert:fs.readFileSync('/path/certificate.pem') }; var tls=require('tls'); var host='server_host'; var port=4001; var client=tls.connect(port,host,options,function(){ console.log('authorized:'+client.authorized); //1) console.log('connected'); client.on('data',function(data){ console.log('data:'+data); }); client.write('Hello'); }); |
2) 데이터 송,수신은 일반적 Stream 과 동일함 (data event, write/end method등)
* TLS Chat Server/Client 예제
- 인증서 생성
openssl genrsa -out server_key.pem 1024
openssl req -new -key server_key.pem -out server_csr.pem
openssl x509 -req -in server_csr.pem -signkey server_key.pem -out server_cert.pem
openssl genrsa -out client_key.pem 1024
openssl req -new -key client_key.pem -out client_csr.pem
openssl x509 -req -in client_csr.pem -signkey client_key.pem -out client_cert.pem
- TLS Server
var tls=require('tls'); var fs=require('fs'); var clients=[]; var serverOptions={ key:fs.readFileSync('./server_key.pem'), cert:fs.readFileSync('./server_cert.pem'), requestCert:true //,rejectUnauthorized:true 1) //,ca:fs.readFileSync('./client_cert.pem') 2) }; function distribute(from,data){ var socket=from.socket; clients.forEach(function(client){ if(client!==from){ client.write(socket.remoteAddress+':'+socket.remotePort+' said:'+data); } }); } var server=tls.createServer(serverOptions,function(client){ console.log('client.authorized:',client.authorized); 3) clients.push(client); client.on('data',function(data){ distribute(client,data); }); client.on('close',function(){ console.log('closed connection'); clients.splice(clients.indexOf(client),1); }); }); var port=4001; server.listen(port,function(){ console.log('listening on port',server.address().port); }); |
1) rejectUnauthorized를 True로 설정하면 client cert가 인증되지 않으면 접속을 거부한다.
2) client_cert를 CA로 지정하면 3)에서 true로 출력되고 1)을 설정해도 접속 가능하다.
- TLS Client
var tls=require('tls'); var fs=require('fs'); var port=4001; var host='0.0.0.0'; var options={ key:fs.readFileSync('client_key.pem'), cert:fs.readFileSync('client_cert.pem') //ca:fs.readFileSync('server_cert.pem') 1) }; process.stdin.resume(); var client=tls.connect(port,host,options,function(){ console.log('connected..server authorized:'+ client.authorized); //2) process.stdin.pipe(client,{end:false}); client.pipe(process.stdout); }); |
1) ca를 서버 certificate로 설정하면 2)에서 true를 리턴함