SQL Server CLR Integration 설정 및 보안 가이드
1. CLR Integration 옵션 켜기
CLR을 사용하기 위해서는 sysadmin
권한이 필요합니다.
EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;
GO
서비스 영향
-
SQL Server 서비스 재시작 불필요
RECONFIGURE
실행 시점에 즉시 적용되므로 프로세스가 재시작되지 않습니다. -
세션/트랜잭션 영향 없음
기존 연결 세션, 실행 중인 쿼리, 트랜잭션에는 영향을 주지 않습니다.
(옵션 플래그만 켜지는 것이므로 DB 멈춤이나 DDL 락은 발생하지 않음)
2. 주의할 점
CLR 활성화 자체는 위험하지 않지만, 이후 어셈블리 배포 및 실행 과정에서 보안 이슈가 발생할 수 있습니다.
- Permission Set 차이: SAFE / EXTERNAL_ACCESS / UNSAFE
- TRUSTWORTHY 옵션 여부
- 해시 기반 어셈블리 신뢰 등록 필요 (
sp_add_trusted_assembly
)
운영 서버라면 옵션 켜기는 안전하지만, 실제 어셈블리 배포/실행은 반드시 테스트 후 진행을 권장합니다.
3. TRUSTWORTHY 옵션 관리
- 기본값은
OFF
ON
으로 설정하면 DB 전체를 “신뢰” 상태로 두어, 소유자 권한 승계를 통한 보안 리스크가 커집니다.- 따라서
TRUSTWORTHY ON
은 비권장입니다.
🔗 참고: TRUSTWORTHY Database Property (MS Docs)
4. 어셈블리 해시 기반 신뢰 등록
SQLCLR 어셈블리를 등록할 때는 SHA2-512 해시 기반 화이트리스트 등록을 권장합니다.
-- 1) SHA2_512 해시 계산
DECLARE @bin VARBINARY(MAX);
SELECT @bin = BulkColumn
FROM OPENROWSET(BULK 'C:\sqlclr\SqlFunctionLib.dll', SINGLE_BLOB) x;
DECLARE @hash VARBINARY(64) = HASHBYTES('SHA2_512', @bin);
SELECT @hash AS sha2_512_hash; -- 확인용
-- 2) 신뢰 등록
EXEC sys.sp_add_trusted_assembly
@hash = @hash,
@description = N'SqlFunctionLib 2025-08-18';
DLL 존재 여부 확인:
EXEC master.dbo.xp_fileexist 'C:\sqlclr\SqlFunctionLib.dll';
5. Permission Set 비교
🔹 SAFE
- 제한 범위: SQL Server 내부 리소스만 사용 가능
- 보안성: 가장 안전
- 제약: 네트워크/파일 접근 불가 → 외부 API 호출 불가
🔹 EXTERNAL_ACCESS
- 제한 범위: 파일, 네트워크, 레지스트리 등 접근 가능
- 보안성: 중간 수준
- 제약:
ThreadPool
,HttpClient
등 일부 API는 HostProtectionException 발생
🔹 UNSAFE
- 제한 범위: Full Trust (모든 .NET 기능 사용 가능)
- 보안성: 가장 위험 (SQL Server 프로세스 권한 그대로 사용)
- 장점: 네트워크/멀티스레딩 정상 동작 → 외부 API 비동기 호출 가능
👉 외부 API 호출이 필요한 경우 UNSAFE 권한 필요
6. 배포 절차 예시
-- 기존 객체 제거
DROP PROCEDURE [Http_FireAndForgetPost];
DROP ASSEMBLY [SqlFunctionLib];
-- 새 DLL 해시 계산 및 신뢰 등록
DECLARE @bin VARBINARY(MAX);
SELECT @bin = BulkColumn
FROM OPENROWSET(BULK 'C:\sqlclr\SqlFunctionLib.dll', SINGLE_BLOB) AS x;
DECLARE @hash VARBINARY(64) = HASHBYTES('SHA2_512', @bin);
EXEC sys.sp_add_trusted_assembly
@hash = @hash,
@description = N'SqlFunctionLib (POST, yyyy-MM-dd HH:mm)';
-- 어셈블리 로드
USE apt_temp01;
CREATE ASSEMBLY [SqlFunctionLib]
FROM 'C:\sqlclr\SqlFunctionLib.dll'
WITH PERMISSION_SET = UNSAFE;
-- 함수 바인딩
CREATE PROCEDURE dbo.Http_FireAndForgetPost
@url NVARCHAR(2048)
AS EXTERNAL NAME [SqlFunctionLib].[HttpAsync].Http_FireAndForgetPost;
7. 발생 가능한 문제 시나리오
- 보안 위험: 외부 API 악성 응답 → SQL Server 프로세스 권한으로 실행됨
- 무한 루프/Deadlock 위험: 잘못된 코드 배포 시 DB 서버 전체 영향
- 방어 방법:
- DLL 해시 기반 등록(
sp_add_trusted_assembly
) - DLL 배포 경로 및 변경 관리 철저
- 트리거 내부에서는 반드시 Fire-and-Forget 패턴 사용
- DLL 해시 기반 등록(
8. Fire-and-Forget 패턴
- 트리거 실행 시 즉시 반환
- 비동기 ThreadPool에서 외부 API 호출
- DB 트랜잭션 지연 최소화 → 안정적인 이벤트 처리 가능
✍️ 정리:
- CLR 옵션 켜기 자체는 안전
- 실제 DLL 배포는 UNSAFE 필요 → 반드시 신뢰된 DLL만 등록
- 운영 환경에서는 해시 기반 등록 + Fire-and-Forget 패턴을 조합해야 안전합니다.