session 파일 저장경로에 따른 가비지 컬렉터 작동 여부

매출이 오르면 내리는 수수료! 지금 수수료센터에서 전자결제(PG)수수료 비교견적 신청해 보세요!
session 파일 저장경로에 따른 가비지 컬렉터 작동 여부

QA

session 파일 저장경로에 따른 가비지 컬렉터 작동 여부

본문

최신 그누보드에서는 session파일을 html/data/session디렉토리가 아니라 /var/lib/php/sessions 디렉토리에 저장하고 있습니다.

 

그런데 문제는 /var/lib/php/sessions에 저장되는 세션 파일이 session.gc_maxlifetime 설정에 따라 삭제되지 않는 다는 것 입니다.

 

common파일의 세션파일 저장위치 주석을 풀어서 html/data/session디렉토리에 세션파일이 저장되게 수정하면 session.gc_maxlifetime 설정에 맞춰서 잘 삭제되어집니다. 

 

html/data/session디렉토리를 사용하지 않는 것이 보안상의 문제 때문이라고 보았는데, /var/lib/php/sessions디렉토리를 세션 파일 저장소로 사용하면서도 session.gc_maxlifetime설정에 따라 삭제되도록 하려면 어떻게 해야 할까요

이 질문에 댓글 쓰기 :

답변 3

/var/lib/php/sessions 디렉토리에 세션 파일을 저장하면서

session.gc_maxlifetime 설정에 따라 삭제되도록 하려면,

PHP의 세션 정리 작업(Garbage Collection, GC)이 정상적으로 동작하도록 설정을 조정.

주된 문제는 PHP의 GC가 기본적으로 cron 작업이나 OS의 환경 설정에 의존하기 때문에,

의도한 대로 작동하지 않을 수 있다는 점입니다.

아래 단계에 따라 설정을 조정해 보세요

 

1. php.ini 설정 확인 및 수정:

session.save_handler를 기본값인 files로 유지.

session.save_path를 /var/lib/php/sessions로 설정.

session.gc_probability와 session.gc_divisor를 조정하여 세션 GC가 실행될 확률을 높임.

*예를 들어:


session.save_handler = files
session.save_path = /var/lib/php/sessions
session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440

2. PHP 세션 디렉토리의 퍼미션 확인:

/var/lib/php/sessions 디렉토리에

PHP 실행 사용자(apache, www-data 등)가 읽기 및 쓰기 권한을 가지고 있는지 확인.


sudo chown -R www-data:www-data /var/lib/php/sessions
sudo chmod 700 /var/lib/php/sessions

3. cron 작업 설정 (필요시):

- PHP의 GC가 동작하지 않을 경우, 직접 cron 작업으로 세션 정리를 수행할 수 있습니다.

*/var/lib/php/sessions의 오래된 파일을 주기적으로 삭제하는 명령을 추가합니다


find /var/lib/php/sessions -type f -mmin +$((session.gc_maxlifetime/60)) -delete

- 위 명령을 crontab에 추가하여 주기적으로 실행되도록 설정합니다.

  예를 들어, 매 30분마다 실행하려면:


*/30 * * * * find /var/lib/php/sessions -type f -mmin +24 -delete

4. lib/common.lib.php 파일의 세션 관리 확인 :

lib/common.lib.php 파일의 세션 관리 부분을 확인하고,

session_save_path 설정이 /var/lib/php/sessions로 되어 있는지 검토.

필요 시 common.lib.php에서 session_save_path를 강제 지정할 수 있음

session_save_path('/var/lib/php/sessions');

 

세션이 지정된 시간(session.gc_maxlifetime) 이후에 정상적으로 삭제됨을 확인할 수 있음.
*해결하는 가장 확실한 방법은
  - PHP 설정 및 cron 작업을 병행하여 환경에 맞게 조정하는 것.
  - 보안 문제를 최소화하려면

    /var/lib/php/sessions 대신 별도의 세션 디렉토리를 지정하고, 적절한 퍼미션을 설정.

 

= = = 추가 팁  문답 = = =
※ 세션 관리와 관련된 다른 환경 요소나 PHP 자체의 GC 메커니즘 동작.

*세션 파일 대신 데이터베이스에 세션을 저장하며, 보안과 관리의 유연성이 증가 됨.

  - PHP 기본 세션 핸들러 대신,

    사용자 정의 세션 핸들러를 구현하여 파일 대신 데이터베이스를 사용하거나,

    더 정밀한 GC 로직을 설정할 수 있음

1. 세션 테이블 생성:

CREATE TABLE custom_sessions (
    id VARCHAR(255) PRIMARY KEY,
    access TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    data TEXT NOT NULL
);
2. 사용자 정의 세션 핸들러 등록:

class CustomSessionHandler implements SessionHandlerInterface {
    private $pdo;
    public function __construct($pdo) {
        $this->pdo = $pdo;
    }
    public function open($savePath, $sessionName) {
        return true;
    }
    public function close() {
        return true;
    }
    public function read($id) {
        $stmt = $this->pdo->prepare("SELECT data FROM custom_sessions WHERE id = :id");
        $stmt->execute([':id' => $id]);
        return $stmt->fetchColumn() ?: '';
    }
    public function write($id, $data) {
        $stmt = $this->pdo->prepare("REPLACE INTO custom_sessions (id, data) VALUES (:id, :data)");
        return $stmt->execute([':id' => $id, ':data' => $data]);
    }
    public function destroy($id) {
        $stmt = $this->pdo->prepare("DELETE FROM custom_sessions WHERE id = :id");
        return $stmt->execute([':id' => $id]);
    }
    public function gc($maxlifetime) {
        $stmt = $this->pdo->prepare("DELETE FROM custom_sessions WHERE access < NOW() - INTERVAL :maxlifetime SECOND");
        return $stmt->execute([':maxlifetime' => $maxlifetime]);
    }
}
$pdo = new PDO('mysql:host=localhost;dbname=your_db', 'username', 'password');
$handler = new CustomSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();

 

※ 세션 보안을 강화한 별도 경로 사용

기존 경로에서 보안 문제가 발생한 점을 고려하여,

다음과 같이 보안을 강화한 별도 경로를 생성하고 사용하는 것을 고려:

1. 별도 세션 경로 생성:

sudo mkdir -p /secure/php/sessions
sudo chown -R www-data:www-data /secure/php/sessions
sudo chmod 700 /secure/php/sessions
2. php.ini 설정 변경:

session.save_path = "/secure/php/sessions"

세션 보안을 강화한 별도 경로 사용은 생각해보지 못했는데, 예시로 보여주신 /secure/php/sessions에서 secure부분을 암호화 처럼 /jhwlzzmeninlwjk224ndfkslg@2nkl/php/sessions처럼 사용하라는 말씀이신거죠?

/secure/php/sessions 경로를 암호화된 디렉터리 이름처럼 보이도록 설정하는 것도
보안 강화에 도움을 줄 수 있습니다.

다만, 디렉터리 이름 자체를 암호화된 형태로 만드는 것은
보안을 위한 핵심적인 방법이라기보다는 보안 레이어를 조금 더 추가하는 의미로 볼 수 있습니다.

제가 제안한, 보안을 강화한 별도 경로 사용은
디렉터리 이름을 복잡하게 지정하여
공격자가 세션 파일 경로를 추측하기 어렵게 만드는 것을 의도한 방법이였습니다.

이는 기본적으로 보안성을 높이기 위해 일반적인 경로(/var/lib/php/sessions) 대신
독창적이고 복잡한 이름의 경로를 사용하는 전략입니다.

근데 왜 세션 보관을 디폴트 경로로 저장하나요?

 

https://github.com/gnuboard/gnuboard5/issues/175
세션 파일에 소셜로그인 API 비밀키 등이 노출될 수 있는 보안취약점이 있었죠.

아주 오래전부터 있었던 문제이고, data 폴더에 세션파일을 저장하지 않도록 변경되었고 그리 오래되지 않았습니다.

이 세션파일에 대한 접근을 서버측에서 잘 차단했으면 예방할 수 있는 부분이지만
sir.kr 조차도 이 문제로 인해 소셜로그인 비밀키를 아주 쉽게 확인할 수 있었죠.

이 문제로인해 캡챠 또한 쉽게 뚫리는 보안취약점 또한 내재하고 있습니다.
캡챠를 켜놔도 뚫고 들어오는 스팸봇으로 문제를 겪고있다면, 이 세션파일에 대한 접근 취약점을 활용하고 있을 수 있습니다.

거의 퍼미션 문제 아닌가요 

/var/lib/php/sessions 폴더 권한 찍어보시는게 제일 먼저 해볼일 같습니다

답변을 작성하시기 전에 로그인 해주세요.
전체 0
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT