코드 블록 오류: 403 Forbidden

최근 Discourse 서버를 관리하게 되었는데 몇 가지 문제가 있습니다.

  1. 코드 블록이 포함된 게시물을 생성하거나 편집할 때 지속적인 문제가 발생합니다. 코드 블록을 포함하여 게시물을 생성하거나 편집하려고 하면
(access node)$ spack list openfoam@2306
...
Variants:
    Name [Default]            When    Allowed values    Description
    ======================    ====    ==============    ==================================================

    build_system [generic]    --      generic           Build systems supported by the package
    int64 [off]               --      on, off           With 64-bit labels
    kahip [off]               --      on, off           With kahip decomposition
    knl [off]                 --      on, off           Use KNL compiler settings
    metis [off]               --      on, off           With metis decomposition
    mgridgen [off]            --      on, off           With mgridgen support
    paraview [off]            --      on, off           Build paraview plugins and runtime post-processing
    precision [dp]            --      sp, dp, spdp      Precision option
    scotch [on]               --      on, off           With scotch/ptscotch decomposition
    source [on]               --      on, off           Install library/application sources and tutorials
    vtk [off]                 --      on, off           With VTK runTimePostProcessing
    zoltan [off]              --      on, off           With zoltan renumbering
...

이와 같이 작성하면 403 Forbidden 오류가 발생합니다.

  1. 마크다운은 코드 하이라이팅을 지원하지 않으며, 어떤 구문 사양을 추가해도 403 Forbidden 오류가 발생합니다.

  2. 인라인 코드 조각도 다른 코드 블록에 대한 상대적 위치에 따라 일부 위치에서만 403 Forbidden 오류를 일으킵니다.

설치된 버전은 3.1.1입니다 ( 0612f0d5b6 ).

이 문제들은 서로 관련이 있으며, 이러한 동작을 일으키는 원인은 무엇일 수 있을까요?

예시 게시물: Compiling OpenFOAM with Spack - 📚 Knowledge nuggets - HPC discourse

의도된 결과:

OpenCFD의 OpenFOAM을 Spack으로 설치할 때 몇 가지 문제가 있습니다.

UL HPC 튜토리얼의 지침에 따라 Spack으로 패키지를 관리하기 위한 환경이 설정되었습니다. 간단히 말해, SPACK 패키지에 대해 다음 종속성이 정의되었습니다.

(access node)$ cat << EOF >> $SPACK_ROOT/etc/spack/packages.yaml
packages:
    slurm:
        externals:
        - spec: slurm@22.05.5
          prefix: /usr
        buildable: False
    libevent:
        externals:
        - spec: libevent@2.1.8
          prefix: /usr
        buildable: False
    pmix:
        externals:
        - spec: pmix@4.2.3 
          prefix: /usr
        buildable: False
    hwloc:
        externals:
        - spec: hwloc@2.2.0
          prefix: /usr
        buildable: False
EOF

그리고 빌드 캐시 디렉토리에 대해 다음 옵션이 정의되었습니다.

(access)$ cat << EOF >> $SPACK_ROOT/etc/spack/config.yaml
config:
    build_stage:
        - /dev/shm/$user/spack-stage
EOF 

이를 통해 램디스크 파일 시스템을 사용하여 컴파일을 가속화했습니다. OpenFOAM 설치를 진행하기 전에, 시스템 컴파일러를 사용하여 원하는 버전의 Open MPI를 설치합니다.

(compute node)$ spack install -j openmpi@4.0.5 +pmi schedulers=slurm ^pmix@4.2.3 ^hwloc@2.2.0

OpenFOAM 배포판도 시스템 컴파일러를 사용하여 설치됩니다. OpenFOAM의 사용 가능한 구성 요소는 다음과 같습니다.

(access node)$ spack list openfoam@2306
...
Variants:
    Name [Default]            When    Allowed values    Description
    ======================    ====    ==============    ==================================================

    build_system [generic]    --      generic           Build systems supported by the package
    int64 [off]               --      on, off           With 64-bit labels
    kahip [off]               --      on, off           With kahip decomposition
    knl [off]                 --      on, off           Use KNL compiler settings
    metis [off]               --      on, off           With metis decomposition
    mgridgen [off]            --      on, off           With mgridgen support
    paraview [off]            --      on, off           Build paraview plugins and runtime post-processing
    precision [dp]            --      sp, dp, spdp      Precision option
    scotch [on]               --      on, off           With scotch/ptscotch decomposition
    source [on]               --      on, off           Install library/application sources and tutorials
    vtk [off]                 --      on, off           With VTK runTimePostProcessing
    zoltan [off]              --      on, off           With zoltan renumbering
...

OpenFOAM은 사용 가능한 모든 파티셔너(metis, scotch, zoltan, kahip)와 멀티그리드 생성기 구성 요소(mgridgen, 문서 6.3.1.4 섹션)를 사용하여 다음 명령어로 설치됩니다.

(compute node)$ spack install -j openfoam@2306 +source precision=dp +metis +scotch +zoltan +kahip +mgridgen ~knl ~int64 ~paraview ^openmpi@4.0.5 

그러나 결과 설치에는 여러 구성 요소가 누락되어 있습니다. 예를 들어 doc/Build.md의 수동 설치 후 검증을 실행하면,

# Create the user "run" directory:
mkdir -p "$FOAM_RUN"
# Change to the user "run" directory:
run
# Copy tutorial
cp -r "$FOAM_TUTORIALS"/incompressible/simpleFoam/pitzDaily ./
# Run the tutorial
( cd pitzDaily && blockMesh && simpleFoam )

메시 생성기 blockMesh와 솔버 simpleFoam이 모두 누락되어 있습니다.

METIS 파티셔너가 여러 구성 요소의 설치를 실패하게 만드는 것으로 밝혀졌습니다. SCOTCH 파티셔너만 사용하여 다시 컴파일하면,

(compute node)$  spack install openfoam@2306  +source +scotch +mgridgen precision=dp ~int64 ~kahip ~knl ~metis ~paraview ~vtk ~zoltan ^openmpi@4.0.5

이 문제가 해결됩니다. 모든 솔버 구성 요소가 설치되지만, 일부 유틸리티는 여전히 누락되어 있습니다.

다음 스크립트를 사용하여 누락된 모든 구성 요소를 감지합니다.

(access node)$ cat list_spack_openfoam 
#!/usr/bin/bash

set -euo pipefail

declare variant="${1}" # e.g. @2306%gcc@8.5.0 @2306+mgridgen
declare type="${2}" # solvers, utilities

find_makefile_directories() {
    local directory="${1}"

    find "${directory}" -type d | grep -E '\/Make$' || true
}

extract_executable_name() {
    local makefile_directory="${1}"

    cat "${makefile_directory}/files" | ( grep -E '^EXE[[:space:]]*=' || true ) | sed 's/^EXE[[:space:]]*=[[:space:]]*\$(FOAM_APPBIN)\///g'
}

main() {
    local variant="${1}"
    local type="${2}"

    local foam_location="$(spack location -i openfoam"${variant}")"

    local pagkage_directory=""
    local executable_name=""
    local installed=""
    local package_makefile_directory=""
    while read -r package_makefile_directory; do
        executable_name=$( extract_executable_name "${package_makefile_directory}" )
        
        if [ -n "${executable_name}" ]; then
            if [ -x "${foam_location}/platforms/linux64GccDPInt32-spack/bin/${executable_name}" ]; then
                installed="Y"
            else
                installed="N"
            fi
            package_directory="$( echo "${package_makefile_directory}" | xargs -I % dirname % )"
            
            echo "${installed} : ${executable_name} => ${package_directory#${foam_location}}"
        fi
    done < <( find_makefile_directories "${foam_location}/applications/${type}" )
}

main "${variant}" "${type}"

스크립트를 간단히 실행하면 다음 유틸리티가 누락되어 있음을 알 수 있습니다.

(access node)$ ./list_spack_openfoam utilities @2306 | grep -E '^N'
N : addr2line => /applications/utilities/miscellaneous/OSspecific/addr2line
N : foamyHexMeshSurfaceSimplify => /applications/utilities/mesh/generation/foamyMesh/foamyHexMeshSurfaceSimplify
N : foamyHexMeshBackgroundMesh => /applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh
N : cellSizeAndAlignmentGrid => /applications/utilities/mesh/generation/foamyMesh/cellSizeAndAlignmentGrid
N : foamToCcm => /applications/utilities/mesh/conversion/ccm/foamToCcm
N : ccmToFoam => /applications/utilities/mesh/conversion/ccm/ccmToFoam

확대하기는 어렵습니다. 마크다운 관련 문제는 403 오류보다는 작성자에게 UI 피드백으로 표시되는 경향이 있습니다. 저희 403 오류는 권한(authorisation)과 관련이 있는 경우가 많으며, 예를 들어 제한된 카테고리에 게시하거나 제한된 태그를 사용하는 것과 같은 문제입니다.

해당 텍스트 조각을 Discourse의 기본(banilla) 인스턴스에서 테스트해 보았는데, 문제가 없는 것으로 보입니다.

당신의 moderator에게 해당 제한 사항이 설정되어 있는지 확인해 달라고 제안합니다.

이어서 말씀드리자면, 게시물을 생성할 때(특히 코드 블록을 포함할 때!) 발생하는 이러한 403 오류는 대부분 과도하게 작동하는 WAF가 코드 블록을 셸코드나 인젝션 공격으로 오인하여 발생하는 경우가 거의 항상입니다.

해당 인스턴스가 WAF 뒤에 있는 것 같습니다:

○ → host hpc-discourse.uni.lu
hpc-discourse.uni.lu is an alias for fstc-waf2.uni.lu.

따라서 403 오류가 Discourse에서 발생하는 것이 아니라 WAF에서 발생한다고 강력히 추정합니다.

브라우저에서 오류 헤더를 검사하면 거부된 출처를 파악할 수 있을 것입니다.