H
H
haik_vm2013-07-17 21:02:17
Nginx
haik_vm, 2013-07-17 21:02:17

Access to the server with SMS authorization through nginx

Here for the client it was necessary to organize SMS authorization.
The client has a large web application that can only be accessed with a username and password. But besides this, the client also wanted to do authorization via SMS. There is no way to get into the application and embed a check there, and the client’s paranoia set the task so that without SMS authorization there should be no access to the application at all. Well. Once asked, we decided to do it.


Installed nginx and apache on the server. Apache has two virtual hosts on different ports. 88 and 8080. These ports on the server are closed from the outside.
nginx hangs on port 80, which is the only open one.

By default, nginx proxies all requests to port 88. Our SMS authorization system lies there. A person enters a username and password, for this pair our application receives a phone number, sends SMS to this phone with a randomly generated code. The user receives SMS, enters the code. Our application compares it with what was sent, if everything is OK, then sets the AUTH cookie to the user. It sets a unique string of 32 completely random characters. And besides that, it throws a file with the same name on the disk. After that it refreshes the page.
The user is again met by nginx. It takes a cookie, sees if there is such a file on the disk, and if so, it proxies the user's request to the client application. Cookie lives session. While there is a cookie, the person uses the client application. If the session is over, then the person will be met again by our authorization system.

Here is a piece of the nginx config that is responsible for checking:

set $flag 0;
if (-f /tmp/auth/$cookie_AUTH) {
  set $flag 1;
}
set $folder 'www';
if ($flag = 1) {
  set $folder 'wwwApp';
}
root /home/$folder;
index  index.html index.htm index.php;
location / {
  if ($flag = 1) {
    proxy_pass http://127.0.0.1:8080;
  } proxy_pass http://127.0.0.1:88;
}


It turned out that nginx pulls the disk for the presence of a file on absolutely every hit. Whether js, jpeg or something else is requested, it still checks for the existence of the file each time. Although there are not many users, they decided to move the storage location of these files to a ram disk in order to reduce the number of disk accesses.

We encountered the organization of such authorization for the first time and invented the bike ourselves :)
Maybe someone will advise a more beautiful version of the implementation of such a thing?
Well, are there any directly obvious disadvantages of this solution?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
R
rozhik, 2013-07-17
@rozhik

I'll write it out in more detail.
So we have 2 drawbacks 1) an extra check for the existence of the file. 2) the cost of creating this flag file and cleaning it up.
Idea here . Create a hash like

$expire = time() + 3600; //Время, на которое даём доступ
$hash = $expire.':'.md5($secret  . $expire); // Вот это шлём в куки значение

Further in nginx on lua, pearl or module we do
// Это псевдокод
list( $expire, $md5 ) = explode( $cookieValue ); 
if( $cookieValue == $expire.':'.md5($secret  . $expire) && $expire >= time() ) {
  // Авторизированы
} else {
  // Не авторизированы
}

The above idea has a drawback - you need to either update the cookie sometimes, or set a long session lifetime. But there are no disk accesses.

R
rozhik, 2013-07-17
@rozhik

There is a secure link module. Based on a trivial idea. Read about it. A cookie is signed there for a while.

V
Vasily, 2013-07-18
@VasiliyIsaichkin

Another option is to read data from memcahe (nginx can do this by default) into a variable using the eval module (www.grid.net.ru/nginx/eval.ru.html‎)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question