어셈블리 언어로 작성된 경량 웹 포럼 엔진 AsmBB
(asmbb.org)- AsmBB는 JohnFound가 만든 빠르고 가벼운 웹 포럼 엔진으로, 어셈블리 언어와 SQLite 기반 구조를 통해 작은 서버에서도 포럼을 운영할 수 있게 함
- x86 Linux 서버에서 32비트와 64비트를 모두 지원하며, 별도 사전 설치 라이브러리 없이 VPS나 FastCGI 지원 공유 호스팅에서도 실행 가능함
- 보안은 적은 의존성과 내부 설계를 강조하며, v2.7의 SQLeet 암호화 데이터베이스와 v3.0의 SQLite3MultipleCiphers 지원으로 이어짐
- 테마, 템플릿 커스터마이징, MiniMag·BBCode, 첨부 파일, 제한 접근 스레드, 실시간 채팅, Atom/RSS, SSE 알림, 다국어 UI, YouTube 임베딩, 스레드 랭킹까지 기능이 확장됨
- v3.0은 데이터베이스와 템플릿 구조에 비호환 변경이 있어, v2.9.1에서 올릴 때 복호화, 백업, 스키마 변경, 바이너리와
templates/교체가 필요함
AsmBB의 구조와 실행 환경
- AsmBB는 웹 포럼 엔진이며, AsmBB.org 포럼도 AsmBB 위에서 동작함
- 전체가 어셈블리 언어로 작성되어 있고 데이터베이스 백엔드로 SQLite를 사용함
- 약한 호스팅 환경에서도 많은 방문자를 지연 없이 처리할 수 있다는 점을 내세움
- 실행 요구사항은 낮은 편임
- x86 Linux 서버 필요
- 32비트와 64비트 모두 지원
- 특별히 사전 설치된 라이브러리 불필요
- 가장 작거나 저렴한 VPS에서도 가능
- FastCGI를 지원한다면 공유 호스팅에서도 가능
- FastCGI 인터페이스를 지원하는 웹 서버 필요
- 테스트된 웹 서버는 Nginx, Apache, Lighttpd, Hiawatha, RWASA임
보안과 암호화 데이터베이스
- AsmBB는 내부 설계와 적은 의존성을 바탕으로 보안성이 높은 웹 애플리케이션을 지향함
- 더 높은 보안을 위해 암호화 데이터베이스를 선택적으로 지원함
- v2.7의 주요 변경은 암호화된 포럼 데이터베이스 지원임
- SQLite 플러그인 SQLeet을 사용함
- 명세상 PBKDF2-HMAC-SHA256 키 유도, 16바이트 salt, 12345회 반복 지원
- ChaCha20 스트림 암호와 일회용 키 사용
- Poly1305 인증 태그 사용
- 암호화는 관리자 설정 패널의 새 Encryption 탭에서 켜고 끌 수 있음
- 암호화 키는 디스크에 저장되지 않고 RAM에만 임시 저장됨
- 웹 서버, 백업 서버, 백업 매체가 심각하게 침해돼도 포럼 데이터베이스, 계정 속성, 개인 데이터 노출을 막는 구성을 목표로 함
- 알려진 제약은 엔진이 재시작될 때마다 웹 인터페이스로 암호화 키를 다시 입력해야 한다는 점임
- 우발적 서버 재시작 시 포럼 접근이 한동안 막힐 수 있음
- AsmBB는 오래 실행되고 안정적인 애플리케이션이라 이런 상황이 몇 달 또는 몇 년에 한 번 발생하는 수준이라고 설명함
- 암호화 데이터베이스를 사용할 때는 SSL/TLS 사용이 필수임
커스터마이징과 설치 경로
- AsmBB는 템플릿 시스템을 통해 코드를 직접 수정하지 않고도 포럼을 커스터마이징할 수 있게 함
- 바이너리 패키지는 asmbb.tar.gz에서 받을 수 있으며, 해당 링크는 최신 바이너리 패키지를 가리킴
- 진행 상황 확인, 버그 보고, 소스 복제는 AsmBB source repository에서 가능함
- 자체 서버 설치 문서는 NGINX와 systemd 설치 튜토리얼로 제공됨
- RWASA를 이용하면 2분 미만 설치가 가능하며 비디오 튜토리얼과 YouTube 영상이 제공됨
최근 포럼 변경 사항
- 현재 포럼에는 Glass, Neumor, Poly, Brutal, Joly, Tailwind, Snes 테마가 추가됨
- MiniMag 버튼의 URL 삽입은 선택된 텍스트를 앵커 텍스트로 사용함
- 이메일 검증은 기본 언어 설정에 맞춰 발송됨
- MiniMag 관련 수정이 들어감
- 연락처나 TOS 등에 사용할 page 기능이 구현됨
- API가 구현됨
v3.0의 주요 변경과 업그레이드 주의점
- v3.0에는 여러 새 기능이 추가됨
- 이미지를 직접 붙여넣어 첨부 파일로 추가 가능
- YouTube 비디오 임베딩 지원
- 코드와 템플릿을 단순화하는 통합 글/스레드 편집기 도입
- 스레드 랭킹 추가
- 품질이 낮다는 이유로 Modern 스킨이 프로젝트에서 제거됨
- v3.0은 이전 버전과 비호환 변경을 포함함
- 데이터베이스 구조 변경
- 템플릿 구조 변경
- SQLeet 프로젝트 중단으로 SQLite3MultipleCiphers 암호화 확장 지원이 추가됨
- 바이너리 릴리스 패키지는 이 확장과 함께 컴파일됨
- 발견된 버그와 취약점이 수정됨
- 여러 버그는 hxp CTF event 결과로 발견됨
- v2.9.1에서 v3.0으로 데이터베이스를 업데이트할 때는 순서가 중요함
- 기존 데이터베이스 수정 전 복호화 필요
- 새 SQLite3MultipleCiphers 라이브러리는 기존 SQLeet 라이브러리와 호환되지 않는 모드로 사용됨
- v3.0으로 마이그레이션하기 전에 데이터베이스를 복호화하고, 이후 새 라이브러리로 다시 암호화할 수 있음
- 문제가 생길 경우를 대비해 백업 필요
- SQLite 콘솔에서 제공된 스키마 변경 SQL 실행 필요
- 데이터베이스 스키마 변경 후 엔진을 중지하고
engine,ld-musl-i386.so,libsqlite3.so바이너리 파일을 교체해야 함 - 엔진이 중지된 동안 전체
templates/디렉터리를 새 것으로 교체해야 함 - 엔진을 다시 시작한 뒤 업데이트된 포럼에 문제가 없는지 확인해야 함
- 모든 것이 정상으로 보이면 AsmBB 설정 페이지에서 데이터베이스를 다시 암호화할 수 있음
v2.x 릴리스 흐름
-
v2.9: Urban Sunrise와 편집 경험 개선
- 새 반응형 테마 Urban Sunrise가 추가됨
- 포럼 외관 개선을 목표로 함
- 글 편집기에 포맷 도움말이 내장됨
- 글 편집기와 실시간 채팅에서 Unicode Emoji를 네이티브 방식으로 지원함
- JS 라이브러리를 통한 소스 코드 구문 강조 지원
- 실시간 채팅은 소스 코드를 포함한 여러 줄 글을 받을 수 있음
- AsmBB 엔진과 FreshLib 라이브러리의 보고된 버그가 수정됨
-
v2.8: 버그 수정과 방어 기능
- 여러 버그가 수정됐으며, 일부는 치명적 버그였음
- 새 테마 Modern이 추가됨
- AsmBB가 요청 속도를 감당하지 못하는 드문 경우를 위해 DDOS 보호가 구현됨
- MiniMag와 BBCode 파서용 URL 분석기가 추가되어 사용자 링크의 XSS 공격을 방지함
-
v2.6: 독일어 UI와 SSE 확장
- 독일어 UI 번역을 포함한 첫 공식 버전임
- 다른 번역도 커뮤니티 도움으로 개선됨
- Atom/RSS 피드로 전체 포럼, 특정 태그, 특정 테마를 구독할 수 있음
- 서버 전송 이벤트(SSE) 처리가 처음부터 다시 작성됨
- SSE는 실시간 채팅뿐 아니라 새 글과 사용자 활동 같은 다양한 포럼 이벤트 알림에도 쓰일 수 있게 됨
- 모든 클라이언트를 단일 스레드에서 처리해 많은 방문자를 낮은 서버 부하로 동시에 처리함
- SQLite와 MUSL 라이브러리 최신 버전이 바이너리 패키지에 포함됨
-
v2.5: 다국어 UI와 BBCode
- 사용자 인터페이스 국제화가 도입됨
- 사용자는 포럼 UI 언어를 선택할 수 있음
- 제공 언어는 English, Bulgarian, Russian, French임
- 두 번째 마크업 언어로 BBCode 파서가 추가되어 MiniMag와 BBCode를 모두 이해함
- BBCode는 다른 포럼 엔진에서 마이그레이션하는 스크립트를 만들 때 도움이 됨
sendmail같은 외부 프로그램으로 이메일을 보낼 수 있음
-
v2.4: 첨부, 제한 접근, 채팅 성능
- 글에 파일을 첨부할 수 있고 첨부 권한은 사용자별로 관리됨
- Limited access threads는 스레드 소유자가 접근 가능한 사용자 목록을 지정할 수 있게 함
- 관리자 페이지에서 사용자 권한 편집 가능
- 익명 사용자 권한을 별도로 설정할 수 있어 등록 사용자만 읽을 수 있는 폐쇄형 포럼을 만들 수 있음
- 실시간 채팅 서비스는 단일 스레드에서 모든 연결을 처리하도록 리팩터링됨
- 템플릿 렌더링 엔진, 데이터베이스 스키마, SQL 요청 최적화 뒤 이전 버전보다 약 20% 빠름
-
v2.3: 유지보수와 접근성
- 심각한 버그 2개를 수정한 유지보수 릴리스임
- 접근성을 위해 배경 이미지를
alt텍스트가 있는<img>태그로 교체함 - 이미지가 꺼져 있어도 포럼을 사용할 수 있음
- 채팅용 JS 코드가 정리되고 약간 빨라짐
-
v2.2와 v2.1: 로그인, 복구, 내비게이션
- 지속 로그인, 비밀번호 재설정, 사용자 목록, 채팅 개선을 포함함
- 지속 로그인은 기본적으로 꺼져 있음
- 비밀번호 재설정은 유효한 이메일을 요구하며 로그인 폼 링크에서 접근 가능함
- v2.2는 태그 시스템 기반 Categories 내비게이션을 추가함
- 글 편집/삭제 기록 보존과 복원 기능이 추가됨
-
v2.0: 성능과 코드 보안
- 템플릿 렌더러
render.asm이render2.asm으로 교체됨 - 새 구현은 더 어셈블리 스타일의 알고리듬을 사용해 더 빠르고 메모리를 덜 사용함
- URL 파싱의 연쇄 문자열 비교가 해시 테이블로 교체됨
- AsmBB 속도는 약 두 배가 됨
- OWASP ZAP와 Tinfoil security를 포함한 테스트 도구로 발견된 취약점이 수정됨
- 강한 퍼징과 준 DDOS 부하 테스트 과정에서 발견된 리소스와 메모리 누수가 수정됨
- 리소스와 메모리 할당·해제를 수집해 웹 페이지로 보고하는 디버깅 도구가 구현됨
- 템플릿 렌더러
댓글과 토론
Hacker News 의견들
-
이건 정말 멋지지만, 다음 문장은 많이 의심스러움:
“AsmBB는 내부 설계와 줄어든 의존성 덕분에 매우 안전한 웹 애플리케이션이다.”
잘 검증된 의존성을 쓰는 데도 큰 가치가 있고, Chuck Norris라도 복잡한 소프트웨어를 어셈블리로 짜면 버그를 만들 수밖에 없음
특히 이 프로젝트처럼 문자열 처리를 많이 해야 하는 경우라면 더 그렇다- 제목을 보자마자 같은 생각이 먼저 떠올랐음
예전에 이 프로젝트의 최신 버전을 그대로 호스팅한 CTF 문제로 나왔을 때도 똑같이 느꼈고, 대회 중 최소 8개의 취약점이 발견됐음
https://ctftime.org/task/24399 - 그 문장도 좀 거슬렸음. 보통 이런 주장은 위험 신호처럼 보이지만, 원 작성자가 영어 원어민은 아닌 듯해서 표현을 조금 완화해야 한다는 점을 놓쳤을 수도 있음
예를 들면 “AsmBB는 설계에서 보안을 중시하고 의존성에 덜 의존한다” 정도였으면 나았을 듯
- 제목을 보자마자 같은 생각이 먼저 떠올랐음
-
마음에 들고, 어셈블리어로 밀고 간 점도 대단함. 의존성을 줄이면 공격 표면이 줄어드는 건 맞지만, 그것만으로 “안전하다”고 할 수는 없음
확률적으로는 익스플로잇 가능성을 낮추지만, 어셈블리어는 메모리 안전성이나 다른 보장이 전혀 없어서 위험을 높이기도 함
어느 쪽이 더 큰지는 단정 못 하겠지만, 그래도 어셈블리어 애플리케이션은 매력적임. 보너스로 aarch64로 트랜스파일하면 Pi-Zero나 Pi-W를 벽면 어댑터에 꽂아 돌릴 수도 있겠음
한편 분산 포럼도 틈틈이 조사해 왔음. Usenet이 밀려난 뒤 이런 포럼이 대세가 됐지만, 대체재라면 Usenet의 분산/복제 기능과 phpBB 같은 사용자 경험을 함께 가져야 한다고 봄
분산되고 최종적 일관성을 갖게 만드는 건 훌륭한 분산 시스템 과제라 퍼즐처럼 즐길 수 있음. 비슷한 걸 만든 적이 있다면 꼭 보고 싶음- 어셈블리어 + Linux 커널 ABI 조합은 전통적인 C/C++ 스택보다 안전할 수 있다고 봄. 훨씬 적은 정의되지 않은 동작에 노출되기 때문임
부호 있는 산술 오버플로와 언더플로는 예상대로 동작하고,mmap + MAP_ANONYMOUS로 할당한 메모리는 예상대로 0으로 초기화됨
주소 0을 포함해 매핑되지 않은 주소 공간에 접근하면 예상대로SIGSEGV가 발생함
어셈블러는 C 컴파일러보다 훨씬 적은 가정을 하고 덜 영리하게 굴기 때문에, 기대를 조용히 깨뜨리기보다는 오류에서 바로 터질 가능성이 더 큼
- 어셈블리어 + Linux 커널 ABI 조합은 전통적인 C/C++ 스택보다 안전할 수 있다고 봄. 훨씬 적은 정의되지 않은 동작에 노출되기 때문임
-
푸터 기준으로 처리 시간은 말도 안 되게 빠름. 하지만 문서가 덴마크까지 전송되는 데 500~1000ms가 걸림
이 경우에는 성능 좋은 코드보다 CDN이 더 나아 보이지만, 그래도 인상적인 작업임- 대서양 한가운데 있는 Azores 제도에서도 500ms 안에 로드됐음
- 대형 기술 기업에서 응답 시간 개선을 주도해 본 입장에서는 1초는 꽤 아픔
물론 전송 시간이 큰 비중을 차지하겠지만, 그게 “좋다”고 여겨진다면 좀 힘들어 보임
-
어셈블리 코드로 데이터베이스에는 어떻게 연결하는 건지 궁금함. 어셈블리 라이브러리 같은 게 있나?
이론상으로는 이해되지만, 그런 “간단한” 것들을 직접 쓰는 데 들어갈 노력이 엄청나게 클 것 같음- 생각보다 덜 복잡함. C 호출 규약을 따라 SQLite C 라이브러리 함수를 호출하면 됨
관련 코드는 여기 있음: https://asm32.info/fossil/asmbb/file?name=source/sqlite3.asm... - C도 보통은 먼저 어셈블리로 컴파일됨
어셈블리로 프로그래밍한다는 건 기본적으로 컴파일러가 할 일을 직접 하는 것이고, C 코드가 호출할 수 있는 같은 라이브러리 함수들을 호출할 수 있음
다만 해당 아키텍처의 호출 규약을 따라야 해서 번거롭고 지루하지만, 불가능에 가까운 일은 아님
x64는 레지스터를 먼저 쓰고 다 쓰면 스택으로 넘기는 방식이라 함수 호출이 더 귀찮아졌음. x32는 스택만 써서 훨씬 편했지만, x64 규약은 값을 레지스터에 유지해 더 빠른 코드를 만들 수 있음 - 데이터베이스가 SQLite라고 되어 있으니, 그냥 SQLite 라이브러리에 링크하는 것으로 보임
- 생각보다 덜 복잡함. C 호출 규약을 따라 SQLite C 라이브러리 함수를 호출하면 됨
-
어셈블리로만 쓴 게 아니라, 뒤에는 SQLite가 있음. 많은 애플리케이션처럼 병목은 CPU보다 입출력일 가능성이 큼
- 언어가 병목이라고 가정하고, 실제로는 입출력이나 데이터베이스 설계가 병목인 경우가 많음
물론 내가 본 PHP 코드들을 생각하면 왜 그렇게 느끼는지도 이해는 됨. 하지만 그건 언어 자체보다는 사용 방식의 문제임 - RAM도 요인임. Arduino에서 C로 몇몇 프로그램을 짰는데, 스택과 C 호출 규약이 완전히 낭비라 어셈블리에 잘 맞았을 코드들이 있었음. 예를 들어 재귀 함수가 전혀 없는 경우가 있음
문제는 이식성임. AVR-8을 좋아하지만 요구사항이 커지면 AVR-8은 FPGA 소프트 코어 정도 말고는 갈 곳이 없음
C라면 ARM 마이크로컨트롤러로 옮길 수 있고, 개인적으로 재미는 덜하지만 성능은 더 잘 나옴
AsmBB의 문제도 특정 아키텍처에 묶여 있다는 점임 PRAGMA synchronous를NORMAL로 둔 WAL 모드에서도 그런가? SQLite 전문가는 전혀 아니고, 프로젝트에 쓰려고 들여다보는 중임
- 언어가 병목이라고 가정하고, 실제로는 입출력이나 데이터베이스 설계가 병목인 경우가 많음
-
“게다가 Unicode Emoji 문자를 정말 네이티브한 방식으로 지원한다”고 되어 있는데, 여기서 더 자세히 설명해 줬으면 좋겠음
“정말 네이티브”가 무엇을 뜻하는지 잘 모르겠고, “약간 네이티브”한 방식과 어떻게 다른지도 불명확함- AsmBB의 어셈블리 코드에는 이모지 처리가 전혀 없는 듯해서, 거의 그대로 통과시키는 방식으로 보임
다만 실시간 채팅은 템플릿 일부인 JS 코드에서 이모지 강조 표시를 함:
function formatEmoji(text) {
var emojiRegEx = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/g;
return text.replace(emojiRegEx, '$1');
}
아마 U+00A9, U+00AE, U+2000..3300, U+1F000..1FBFF를 잡으려는 의도였을 텐데, 그 자체로도 너무 넓고 정규식도 충실한 변환이 아님
올바른 해법이 궁금하다면emoji-regex[1]나 더 최근의/\p{RGI_Emoji}/v패턴 [2]을 쓰면 됨
[1] https://unpkg.com/browse/emoji-regex/index.js
[2] https://caniuse.com/mdn-javascript_builtins_regexp_unicodese... - 추측이지만, Twitter 같은 일부 사이트는 자체 이모지 세트를 쓰는데, 여기서는 그런 걸 하지 않고 운영체제의 기본 이모지 렌더링에 맡긴다는 뜻일 수도 있음
- AsmBB의 어셈블리 코드에는 이모지 처리가 전혀 없는 듯해서, 거의 그대로 통과시키는 방식으로 보임
-
헤더에 실시간 알림을 끄는 버튼이 있음
덧붙이면, 로그인하지 않은 사람에게 포럼 사용자 목록을 보여주는 건 별로 좋아 보이지 않음. 설정 가능한 항목인가?- 모바일에서는 실시간 알림을 끄는 버튼을 못 찾았음
- 예전부터 포럼은 원래 그런 식이었고, 아마 설정도 가능할 것임
-
콘셉트와 구현이 정말 좋음. 다만 실시간 알림이 금방 압도적으로 많아져서, 어떤 형태로든 속도 제한이 있어야 할 듯함
@User123 has entered the thread같은 건 모두가 서로를 알던 작은 포럼에서는 잘 맞았을 것 같음
phpBB/vBulletin이 “이 스레드를 읽는 사용자: ...” 목록을 보여준 것도 그런 이유였고,@Foo와@Bar가 이 스레드에 답글을 작성 중이라고 보여주는 인기 플러그인도 있었음
특히 격한 토론 중에는 공간이 더 살아 있는 느낌을 줬고, 상대가 내 글을 인용문 단위로 반박하는 다음 장문의 글을 쓰고 있다는 걸 아는 것도 나름 좋았음
하지만 미등록 게스트가 스레드를 클릭할 때마다 알림을 받는 건 누구에게도 유용해 보이지 않음- 종 아이콘을 누르면 실시간 알림을 끌 수 있음
-
C로도 비슷한 걸 만들고 표준 라이브러리를 포기할 수 있음. 시스템 호출 외에는 의존성이 없게 만들 수 있음
지적 훈련이라는 점 말고는 굳이 어셈블리로 할 강한 이유는 잘 모르겠음 -
제목에는 어떤 어셈블리인지, 심지어 어떤 운영체제에서 돌아가는지도 빠져 있음
“x86 asm”과 “on linux”를 합쳐도 “assembly language”보다 길지 않음